38개 단어(한 줄에 하나씩) 목록이 포함된 "ingredients.txt" 파일이 있습니다. 배열로 읽는 방법을 알아냈습니다.
getArray() {
array=()
while IFS= read -r line
do
array+=("$line")
done < "$1"
}
getArray "ingredients.txt"
하지만 이제 38개 목록에서 정확히 4개 단어의 모든 조합을 출력하는 방법은 무엇입니까?
편집: 의견에 대한 응답으로 순열이 아닌 조합을 의미했으며 중복은 효과가 없습니다. 각 조합에는 4개의 고유한 단어가 있습니다.
좀 더 명확하게 설명하자면, 이것을 가방에서 38가지 색상의 구슬 4개를 뽑는다고 생각해보세요. 두 가지 색상이 동일하지 않습니다. 빨간색 조합을 한 번 그리면 해당 조합에 대해 다른 빨간색 조합을 그릴 수 없습니다. 4개를 칠하고 색상을 기록한 다음 다시 가방에 넣고 4개를 더 칠합니다. {파란색, 노란색, 보라색, 빨간색}과 {노란색, 보라색, 빨간색, 파란색}을 얻으면 별도로 계산되지 않습니다. 나는 단지 순열이 아닌 조합을 원합니다.
또한 양파, 치즈, 고기, 상추, 당근, 셀러리, 무당근, 상추, 셀러리, 식초 등 각 조합(성분 목록으로 돌아가기)을 인쇄하고 싶습니다.
이것이 분명하기를 바랍니다.
답변1
파이썬에서는:
import itertools.combinations
with open('ingredients.txt') as fd:
words= fd.readlines()
for combination in itertools.combinations(words, 4):
print(combination)
답변2
파이썬을 사용해보려고 해요
>>> a
['praveen', 'ajay', 'abhi', 'chetan', 'abh', 'cat']
for i in range(0,len(a),4):
... print a[i:i+4]
...
['praveen', 'ajay', 'abhi', 'chetan']
['abh', 'cat']
답변3
재미를 위해 일반 bash로 작성된 버전입니다(긴 목록과 함께 사용하는 것을 권장하지 않습니다. 매우 느립니다(예상대로). c에서 수행된 작업을 0.5초 안에 수행하는 데 셸에서 2분 이상이 걸립니다.) :
#!/bin/bash -
set -u
readarray -t b <ingredients.txt
r=${1:-3}
n=${2:-5}
main(){
combinations
}
combinations(){ : ${r:=3} ${n:=5} # default values
## The first line of elements is easy, fill an array of r elements:
for ((i=0 ; i<r ; i++)); do
a[i]=$i
done
printelements
## Up to the maximum permitted value of the first array element.
while (( a[0] < n-r )); do
## search backwards on the array for a value less than maximum.
for ((i = r-1; i >= 0; i--)); do
## If an item is below its maximum permitted value...
if ((a[i] < n-r+i )); then
## increment it:
((a[i]++))
break
fi
done
## Fill the rest of the array with consecutive values:
for (( i = i + 1 ; i < r ; i++ )); do
(( a[i] = a[i-1] + 1 ))
done
## Print the current combination of items:
printelements
done
}
printelements(){ : #p=${a[@]/%/ }; printf '%s\n' "<${p% }>"; }
s=""
for i in "${a[@]}"; do
printf '%s' "$s" "${b[i]}"
s=" "
done
echo
}
main
다음과 같이 실행하세요:
$ ./script 4 38
다음을 인쇄합니다:
$ ./script 4 38 | wc -l
73815
수학적으로 확인되는 것처럼(사실은 라이브러리 정의 함수입니다):
$ bc <<<"r=4;n=38;fact(n)/(fact(r)*fact(n-r))" # n! / ( r! × (n-r)! )
73815
답변4
그럼 아래 코드를 사용해 보세요
getArray() {
array=()
while IFS= read -r line
do
array+=("$line")
done < "$1"
for i in ${!array[@]}
do
if [ ${#array[$i]} == 4 ]; then
echo "${array[$i]}"
fi
done
}
getArray "ingredients.txt"