在 bash 中判断三角形是否等腰

Mon*_*lal 0 bash shell if-statement sh

当三角形为等腰三角形时,如何总结这段代码?

  1 #!/bin/bash
  2 
  3 read x y z
  4 
  5 if [[ x -eq z ]] && [[ x -eq y ]] && [[ y -eq z ]]; then
  6   echo EQUILATERAL
  7 elif [[ x -eq z ]] && [[ x -eq y ]]
  8 then
  9   echo ISOSCELES
 10 elif [[ y -eq z ]] && [[ y -eq x ]]
 11 then
 12   echo ISOSCELES
 13 elif [[ z -eq x ]] && [[ z -eq y ]]
 14 then
 15   echo ISOSCELES
 16 else
 17   echo SCALENE
 18 fi
~  
Run Code Online (Sandbox Code Playgroud)

目前实际上代码不起作用:

$ ./triangle.sh 
4 4 6
SCALENE
$ ./triangle.sh 
4 5 5
SCALENE
$ ./triangle.sh 
4 5 3
SCALENE
$ ./triangle.sh 
4 4 4 
EQUILATERAL
$ ./triangle.sh 
2 9 1
SCALENE
$ ./triangle.sh 
2 3 2
SCALENE
Run Code Online (Sandbox Code Playgroud)

小智 5

您的代码几乎是正确的,但每种情况下的测试次数都多于所需的次数。

在:

[[ x -eq y ]] && [[ x -eq z ]] && [[ y -eq z ]] 
Run Code Online (Sandbox Code Playgroud)

如果x=y并且x=z必须遵循那个y=z。没有必要进行这样的测试。

在:

[[ x -eq z ]] && [[ x -eq y ]]
Run Code Online (Sandbox Code Playgroud)

如果x=z两侧值相等,则无需进行任何额外测试。

你的脚本清理了一下就变成了:

#!/bin/bash

read x y z

if   [[ x -eq y ]] && [[ x -eq z ]]; then echo EQUILATERAL
elif [[ x -eq y ]]                 ; then echo ISOSCELES
elif [[ x -eq z ]]                 ; then echo ISOSCELES
elif [[ y -eq z ]]                 ; then echo ISOSCELES
else                                      echo SCALENE
fi
Run Code Online (Sandbox Code Playgroud)

此外,等腰三角形的三个检验可以用 OR ( ||) 在一行中完成:

#!/bin/bash

read x y z

if   [[ x -eq y ]] && [[ x -eq z ]]                 ; then echo EQUILATERAL
elif [[ x -eq y ]] || [[ x -eq z ]] || [[ y -eq z ]]; then echo ISOSCELES
else                                                       echo SCALENE
fi
Run Code Online (Sandbox Code Playgroud)

甚至(利用[[使用):

#!/bin/bash

read x y z

if   [[ x -eq y && x -eq z ]]           ; then echo EQUILATERAL
elif [[ x -eq y || x -eq z || y -eq z ]]; then echo ISOSCELES
else                                           echo SCALENE
fi
Run Code Online (Sandbox Code Playgroud)

请注意,不带 a 的变量名称仅在使用 a进行算术测试$的情况下才起作用。 通常的智慧是为变量使用正确的名称,例如.[[-eq
[[ $x -eq $y ]]


为了涵盖您写的其他答案,这里是一个更正的脚本:

  • 不需要 xplusy 变量
  • 测试可以直接算术
  • 使用参数而不是读取。

#!/bin/bash

triangle(){
    x=$1 y=$2 z=$3
    for i in $x $y $z; do
        if (( i < 1 ||  i > 1000 )); then
            printf '%4d %4d %4d %s\n' "$x" "$y" "$z" "side out of range"
            return 1
        fi
    done

    if (( ! ( x+y > z && y+z > x && z+x > y )  )); then
        printf '%4d %4d %4d %s\n' "$x" "$y" "$z" "not a triangle"
        return 1
    fi

    if   (( x != z && x != y && y != z )); then printf '%4d %4d %4d %s\n' "$x" "$y" "$z" SCALENE
    elif (( x == y && x == z ))          ; then printf '%4d %4d %4d %s\n' "$x" "$y" "$z" EQUILATERAL
    else                                        printf '%4d %4d %4d %s\n' "$x" "$y" "$z" ISOSCELES
    fi
}

triangle 4    4  6
triangle 4    5  5
triangle 4    5  3
triangle 4    4  4
triangle 2    9  1
triangle 2    3  2
triangle 100  3  3
triangle 1    2  1000
triangle 1003 3  3
Run Code Online (Sandbox Code Playgroud)

执行时,脚本将打印:

./script.sh
   4    4    6 ISOSCELES
   4    5    5 ISOSCELES
   4    5    3 SCALENE
   4    4    4 EQUILATERAL
   2    9    1 not a triangle
   2    3    2 ISOSCELES
 100    3    3 not a triangle
   1    2 1000 not a triangle
1003    3    3 side out of range
Run Code Online (Sandbox Code Playgroud)