1

我的代码有什么问题?我正在尝试打印最多 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
4

3 回答 3

2

expr要求将参数作为单独的参数传递。引用POSIX 标准expr

应用程序应确保每个表达式运算符符号 [...] 以及表中的符号整数和字符串作为单独的参数提供给 expr。

这里的代码将所有运算符附加到一个参数中,因此您的问题。


因此:

c=$(expr "$c" + 1)

...不是...

c=$(expr $c+1)

但千万不要这样做。写起来更高效、更易读:

c=$(( c + 1 ))
于 2021-06-02T23:04:45.253 回答
1

优化迭代次数更少的 POSIX shell 版本:

#!/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 '%s\n' "$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 '%s\n' "$i"
  fi
  i=$((i + 2))
done
于 2021-06-03T01:01:01.803 回答
0

不要使用expr. 将您的数学表达式放入其中(( ))(或echo $(( ))打印结果),shell 将对其进行评估。

看看expr输出的样子,与常规的 shell 算术:

$ expr 0+1
0+1
$ echo "$((0+1))"
1

-eq如果两个操作数都不是整数,则withtest或单方括号(例如)会打印错误。[ 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

编辑:只是为了解释一些事情,如果(([expression]))评估为0,它返回非零 ( 1) (失败)。如果计算结果为任何其他数字(正数或负数),则返回零 (true)。当一个数除以 时i,模 ( %)(余数)为零。因此命令失败,我们知道它不是素数,我们可以continue在外循环中获取下一个数字。

于 2021-06-03T01:46:10.153 回答