我的代码出了什么问题?我正在尝试打印n位数以内的素数
echo Enter Number
read num
for (( i=2; $i <= $num ; i++ ))
do
c=0
for (( j=2; $j <= $i ; j++))
do
mod=$(($i % $j))
if [ "$mod" -eq 0 ]
then
c=`expr $c+1`
fi
done
if [ "$c" -eq 1 ]
then
echo $c
fi
done
我不知道自己做错了什么。如果有人能告诉我如何修复它,我会感谢
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
expr
要求参数作为单独的参数传递。引用POSIX标准的expr
:
应用程序应确保表中的每个表达式运算符符号[…]以及符号integer和字符串作为expr的单独参数提供。
这里的代码将所有运算符附加到一个参数中,因此出现了问题。
因此:
c=$(expr "$c" + 1)
不是。。。
c=$(expr $c+1)
但不要这么做。写起来更高效、更可读:
c=$(( c + 1 ))
使用较少迭代进行优化POSIX外壳版本:
#!/usr/bin/env sh
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
c=0
j=2
# Stop checking division when divisor power 2 is greater than number
# or we identifed a divisor
while [ "$((j * j))" -le "$i" ] && [ "$c" -eq 0 ]; do
c=$((i % j == 0))
j=$((j + 1))
done
if [ "$c" -eq 0 ]; then
printf '%sn' "$i"
fi
i=$((i + 2))
done
或者使用一个功能:
#!/usr/bin/env sh
is_prime() {
j=2
# Check j is a divisor of argument number, while j^2 is less than number
while [ "$((j * j))" -le "$1" ]; do
# If j is a divisor of number before the end of the loop
# number is not prime, so return 1
[ "$(($1 % j))" -eq 0 ] && return 1
j=$((j + 1))
done
}
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
if is_prime "$i"; then
printf '%sn' "$i"
fi
i=$((i + 2))
done
不要使用expr
。将您的数学表达式放入(( ))
(或echo $(( ))
以打印结果(中,shell将对其进行求值。
看看expr
输出与常规shell算法相比是什么样子的:
$ expr 0+1
0+1
$ echo "$((0+1))"
1
如果两个操作数都不是整数,则带有test
的-eq
或单方括号(如[ 1 -eq 2 ]
(会打印错误。这就是造成你错误的原因。
这里有一个快速简洁的方法来列出bash中的素数。你可以把它放在一个函数或脚本中:
for ((i=2; i<="${1:?Maximum required}"; i++)); do
for ((j=2; j<i; j++)); do
((i%j)) || continue 2
done
echo "$i"
done
edit:只是为了解释一下,如果(([expression]))
计算为0
,则返回非零(1
((失败(。如果计算结果为任何其他数字(正或负(,则返回零(true(。当一个数等分为i
时,模(%
((余数(为零。因此,命令失败了,我们知道它不是素数,我们可以为下一个数字continue
外循环。