开发者问题收集

将 if-else 语句转换为 switch 语句

2014-05-04
291

我无法将此程序从 if-else 语句转换为 switch 语句。任何帮助都将不胜感激。

#!/bin/bash

for x in $@
do
array[$i]=$x
i=$((i+1))
done


# initial state
state=S0


 for((i=0;i<${#array[@]};i++))
 do

 if [ $state == S0 ] 
  then
   if [ ${array[$i]} == I0 ]
   then
   state=S1
   output[$i]=O1
   elif [ ${array[$i]} ==  I1 ]
   then
   state=S0
   output[$i]=O0
   fi

  elif [ $state == S1 ]
   then
   if [ ${array[$i]} == I0 ]
    then
    state=S1
    output[$i]=O1
    elif [ ${array[$i]} == I1 ]
     then
    state=S0
    output[$i]=O0
    fi
    fi


    done
    echo "final state="$state
    echo "output="${output[@]}

对于那些对脚本感到疑惑的人...这个脚本是关于有限状态机的...这个脚本有两个状态,我想将其转换为 case 语句,以便它更易读且速度更快,特别是对于不像这个这样的大项目。

1个回答

首先,合理缩进对维护代码有很大帮助。

一个错误,在 if 语句中使用单括号 - 如果比较左侧的变量为空,则会出现语法错误。使用双括号或用双引号将变量括起来。这很重要,因为您正在从用户那里获取输入,并且您永远不知道会得到什么。

#!/bin/bash

for x in "$@"; do
    array[$i]=$x
    ((i++))
done

# initial state
state=S0

for ((i=0; i<${#array[@]}; i++)); do
    if [[ $state == S0 ]]; then
        if [[ ${array[$i]} == I0 ]]; then
            state=S1
            output[$i]=O1
        elif [[ ${array[$i]} ==  I1 ]]; then
            state=S0
            output[$i]=O0
        fi
    elif [[ $state == S1 ]]; then
        if [[ ${array[$i]} == I0 ]]; then
            state=S1
            output[$i]=O1
        elif [[ ${array[$i]} == I1 ]]; then
            state=S0
            output[$i]=O0
        fi
    fi
done
echo "final state="$state
echo "output="${output[@]}

我发现无论状态是 S0 还是 S1,您都会做完全相同的事情,因此您可以删除该部分。此外,填充数组变量可以简化。留下:

#!/bin/bash
array=( "$@" )
state=S0

for ((i=0; i<${#array[@]}; i++)); do
    if [[ ${array[$i]} == I0 ]]; then
        state=S1
        output[$i]=O1
    elif [[ ${array[$i]} == I1 ]]; then
        state=S0
        output[$i]=O0
    fi
done

echo "final state: $state"
echo "output: ${output[*]}"

考虑到所有这些,我真的不认为 case 语句对您有帮助。但如果您想要:

#!/bin/bash
array=( "$@" )
state=S0   # initial state

for ((i=0; i<${#array[@]}; i++)); do
    case ${array[$i]} in
        I0) state=S1; output[$i]=O1 ;;
        I1) state=S0; output[$i]=O0 ;;
    esac
done

echo "final state: $state"
echo "output: ${output[*]}"
glenn jackman
2014-05-04