
다음 작업 코드가 있습니다.
largest_prime=1
for number_under_test in {1..100}
do
is_prime=true
factors=''
for ((divider = 2; divider < number_under_test-1; divider++));
do
remainder=$(($number_under_test % $divider))
[ $remainder == 0 ] && [ is_prime ] && is_prime=false && factors+=$divider' '
done
[ $is_prime == true ] && echo "${number_under_test} is prime!" || echo "${number_under_test} is NOT prime (factors= $factors)" [ $is_prime == true ] && largest_prime=$number_under_test
done
printf "\nLargest Prime= $largest_prime\n"
이 코드는 0.194초의 빠른 속도로 실행됩니다. 하지만 && is_prime= false
읽기가 약간 어려웠고 (훈련받지 않은 눈에는) 설정되기보다는 테스트 중인 것처럼 보입니다. 그래서 &&
an 으로 변경해 보았는데 if...then
효과가 있었습니다. 하지만 14.48초로 75배 느렸습니다. 숫자가 높을수록 가장 눈에 띕니다.
largest_prime=1
for number_under_test in {1..100}
do
is_prime=true
factors=''
for ((divider = 2; divider < number_under_test-1; divider++));
do
remainder=$(($number_under_test % $divider))
if ([ $remainder == 0 ] && [ $is_prime == true ]); then
is_prime=false
factors+=$divider' '
fi
done
[ $is_prime == true ] && echo "${number_under_test} is prime!" || echo "${number_under_test} is NOT prime (factors= $factors)" [ $is_prime == true ] && largest_prime=$number_under_test
done
printf "\nLargest Prime= $largest_prime\n"
둔해 보이지 않고 블록을 날카롭게 유지하는 방법이 있습니까?
업데이트됨 (2015년 1월 4일 오전 10시 40분 ET)
좋은 피드백! 현재 다음을 사용하고 있습니다. 다른 제안은 없나요?
largest_prime=1
separator=' '
for number_under_test in {1..100}; {
is_prime=true
factors=''
for ((divider = 2; divider < (number_under_test/2)+1; divider++)) {
remainder=$(($number_under_test % $divider))
if [ $remainder == 0 ]; then
is_prime=false
factors+=$divider' '
fi
}
if $is_prime; then
printf "\n${number_under_test} IS prime\n\n"
largest_prime=$number_under_test
else
printf "${number_under_test} is NOT prime, factors are: "
printf "$factors\n"
fi
}
printf "\nLargest Prime= $largest_prime\n"
답변1
그 이유는 매번 서브쉘을 생성하기 때문입니다.
if ([ $remainder == 0 ] && [ $is_prime == true ]); then
괄호만 제거하면 됩니다
if [ $remainder == 0 ] && [ $is_prime == true ]; then
명령을 그룹화하려면 다음 구문을 사용하면 됩니다.현재의껍데기:
if { [ $remainder == 0 ] && [ $is_prime == true ]; }; then
(후행 세미콜론이 필요합니다.수동)
이는 [ is_prime ]
다음과 다릅니다 . 대괄호 없이 [ $is_prime == true ]
간단히 작성하면 bash 내장 또는 명령이 호출됩니다. 하나의 인수, 문자열 "is_prime"을 취하는 테스트입니다. 인수가 주어졌을 때 인수가 비어 있지 않으면 결과는 성공이고 리터럴 문자열은 항상 비어 있지 않으므로 항상 "true"입니다.$is_prime
true
false
[ is_prime ]
[
가독성을 위해 매우 긴 줄을 바꾸겠습니다.
[ $is_prime == true ] && echo "${number_under_test} is prime!" || echo "${number_under_test} is NOT prime (factors= $factors)" [ $is_prime == true ] && largest_prime=$number_under_test
도착하다
if [ $is_prime == true ]; then
echo "${number_under_test} is prime!"
else
echo "${number_under_test} is NOT prime (factors= $factors)"
# removed extraneous [ $is_prime == true ] test that you probably
# didn't notice off the edge of the screen
largest_prime=$number_under_test
fi
명확성을 높이기 위해 공백을 과소평가하지 마십시오.
답변2
내 생각엔 당신이 당신의 역할을 너무 열심히 하고 있는 것 같아요. 고려하다:
unset num div lprime; set -- "$((lprime=(num=(div=1))))"
while [ "$(( num += ! ( div *= ( div <= num ) ) ))" -eq \
"$(( num *= ( div += 1 ) <= 101 ))" ] && {
set "$(( ! ( num % div ) * div ))" "$@"
shift "$(( ! $1 + ( $1 == 1 ) * $# ))"
}; do [ "$div" -gt "$num" ] && echo "$*"
done
쉘 연산은 자체적으로 정수 조건을 평가하는 능력이 매우 뛰어납니다. 너무 많은 테스트 및/또는 외부 과제가 필요한 경우는 거의 없습니다. 이 while
루프는 중첩 루프를 훌륭하게 복제합니다.
그렇게 많이 인쇄되지는 않을 것이고, 물론 그렇게 많이 쓰지는 않았지만, 예를 들어 위에 적힌 대로 101이 아닌 16으로 상한선을 설정하고...
2
3
4 2
5
6 3 2
7
8 4 2
9 3
10 5 2
11
12 6 4 3 2
13
14 7 2
15 5 3
확실히 그 일을하고 있습니다. 출력을 대략적으로 계산하는 데는 거의 필요하지 않습니다.
...
do [ "$div" -eq "$num" ] && shift &&
printf "$num ${1+!}= prime.${1+\t%s\t%s}\n" \
"factors= $*" \
"lprime=$(( lprime = $# ? lprime : num ))"
done
그냥 대신 해보세요 echo
...
1 = prime.
2 = prime.
3 = prime.
4 != prime. factors= 2 lprime=3
5 = prime.
6 != prime. factors= 3 2 lprime=5
7 = prime.
8 != prime. factors= 4 2 lprime=7
9 != prime. factors= 3 lprime=7
10 != prime. factors= 5 2 lprime=7
11 = prime.
12 != prime. factors= 6 4 3 2 lprime=11
13 = prime.
14 != prime. factors= 7 2 lprime=13
15 != prime. factors= 5 3 lprime=13
이것은 busybox
매우 이식성이 뛰어나고 빠르고 사용하기 쉽습니다.
서브쉘 문제는 대부분의 쉘에서 발생하지만 다음을 통해 수행됩니다.멀리, 껍질 중에서 가장 날카로운 것입니다 bash
. 번갈아가며 해요
( [ "$div" -gt "$num" ] ) && ...
...위에서 한도가 dash
101인 여러 쉘에 작성했는데 서브쉘이 없으면 0.017초, 서브쉘이 있으면 1.8초 만에 완료되었습니다. busybox
.149 및 2, zsh .149 및 4, bash
.35 및 6, ksh93
.149 및 .160. ksh93
다른 쉘처럼 서브쉘을 분기할 필요가 없습니다. 따라서 문제는 서브쉘에 있는 것이 아니라껍데기.