bash脚本执行二进制搜索并将值存储在数组中
我需要一个关于如何完成这个研究项目的想法: 编写一个Bash脚本来执行二进制搜索。将文件中的学生姓名和成绩读入数组。bash脚本执行二进制搜索并将值存储在数组中,bash,sh,binary-search,Bash,Sh,Binary Search,我需要一个关于如何完成这个研究项目的想法: 编写一个Bash脚本来执行二进制搜索。将文件中的学生姓名和成绩读入数组。 提示用户输入学生姓名。在数组中查找名称并显示等级。如果该学生不存在,请打印一条消息说明 文件中的数据如下所示: Ann:A Bob:C Cindy:B Dean:F Emily:A Frank:C Ginger:D Hal:B Ivy:A Justin:F Karen:D 只是一个关于二进制搜索方法的注释。使用“大于/小于”检查用户提供的名称是否低于或高于数组中的当前名称,因为
提示用户输入学生姓名。在数组中查找名称并显示等级。如果该学生不存在,请打印一条消息说明 文件中的数据如下所示:
Ann:A
Bob:C
Cindy:B
Dean:F
Emily:A
Frank:C
Ginger:D
Hal:B
Ivy:A
Justin:F
Karen:D
只是一个关于二进制搜索方法的注释。使用“大于/小于”检查用户提供的名称是否低于或高于数组中的当前名称,因为名称按字母顺序排列(这意味着给您分配此任务的人希望您利用此便利性) 代码:
# Store the names and grades into arrays
names=( $( cut -d: -f1 filename ) )
grades=( $( cut -d: -f2 filename ) )
# Prompt user for a name
echo "Type the student's name (use proper capitalization!), followed by [ENTER]:"
# Read the user's response
read name
length=${#names[@]}
start=0
end=$((length - 1))
match=0
while [[ $start -le $end ]]; do
middle_i=$((start + ((end - start)/2)))
middle_item=${names[$middle_i]}
if [[ $middle_item -gt $name ]]; then
end=$((end - middle_i-1))
elif [[ $middle_item -lt $name ]]; then
start=$((middle_i+1))
else
# A match was found
match=1
echo "${name}'s grade is a(n): ${grades[$middle_i]}."
break
fi
done
# Check if a match was found
if [[ $match = 0 ]]; then
echo "Couldn't find that student..."
fi
如果您不认为二进制搜索是一种可读性很强的方法,那么我建议使用for循环:
# Find the user's provided name, print the
for i in "${!names[@]}"; do
# Check if the current name in the array is the same as the provided name
if [[ "${names[$i]}" = "${name}" ]]; then
# A match was found
match=1
echo "${name}'s grade is a(n): ${grades[$i]}."
break
fi
done
对于cut
命令,如果您不熟悉
-d
:指定给定文本文件中使用的分隔符
-f
:指定要保留的字段(从而存储到数组中)
解释代码:
# Store the names and grades into arrays
names=( $( cut -d: -f1 filename ) )
grades=( $( cut -d: -f2 filename ) )
# Prompt user for a name
echo "Type the student's name (use proper capitalization!), followed by [ENTER]:"
# Read the user's response
read name
length=${#names[@]}
start=0
end=$((length - 1))
match=0
while [[ $start -le $end ]]; do
middle_i=$((start + ((end - start)/2)))
middle_item=${names[$middle_i]}
if [[ $middle_item -gt $name ]]; then
end=$((end - middle_i-1))
elif [[ $middle_item -lt $name ]]; then
start=$((middle_i+1))
else
# A match was found
match=1
echo "${name}'s grade is a(n): ${grades[$middle_i]}."
break
fi
done
# Check if a match was found
if [[ $match = 0 ]]; then
echo "Couldn't find that student..."
fi
:
代替,
作为分隔符。因此,我使用-d:
。文本文件中每行有两列(即两个字段)李>
:
。第一个字段包含学生的姓名,因此我使用-f1
捕获学生的姓名。第二个字段包含学生的成绩,因此我使用-f2
来获取学生的成绩完成了!快乐编码
read-r my_-var
可以从stdin或tty读取:read-r my_-var
我还没有尝试过任何东西。我对shell脚本完全没有兴趣。从今天到明天,我会努力读一些东西。任何支持都会很有帮助。@Robertokipins对手册页很熟悉,例如:man1read
。1
通常可以省略,但可以确保找到可执行文件。有关更多信息,请参见man
:-)。另一个有趣的读物是:不要害怕,但评分员会在你需要的时候把它作为参考。此外,shellcheck是一个很好的工具和网站,可以使用当前的GNUBash编写shell脚本:declare-a数据;而IFS=“:”读取名称等级;do数据[“$name”]=“$grade”;完成<文件;search=“Bob”;echo${data[“$search”]}
这很好,Martin,感谢您提供的所有详细信息和解释。据我所见,有很多方法可以实现这一点,我一定会研究所有的评论,并尝试自己去做。在bash中有很多方法可以做到这一点。如果您计划自己回答这个问题,并且不再寻求StackOverflow的帮助,那么您应该做一些事情来表明您没有从StackOverflow社区寻求答案。我希望这个答案能有所帮助:)顺便说一句(让你知道),这个问题已经在这个网站上被问过了。看看你是否想要更多可能的方法。在我的回答中,技术上我没有提供二进制搜索方法,尽管我的回答肯定会给你一个好的开始。我后来看到了这个问题,但给出的答案没有一个像你的解释那样清晰。这很有帮助,因为我对脚本编写还不熟悉。谢谢!如果那样的话,如果你发现我有助于回答你的问题,那么请考虑接受它。