2016-06-09 57 views
2

我需要如何完成这一研究项目的想法:bash脚本做二进制搜索和存储值数组

写bash脚本做一个二进制搜索。将文件中的学生姓名和成绩读入数组中。
提示用户输入学生姓名。在数组中找到名称并显示分数。如果学生不存在,请打印一条消息说明。

文件中的数据低于:

Ann:A 
Bob:C 
Cindy:B 
Dean:F 
Emily:A 
Frank:C 
Ginger:D 
Hal:B 
Ivy:A 
Justin:F 
Karen:D 
+0

'read -r my_var'可以从stdin或tty读取:'read -r my_var andlrc

+0

我还没有尝试过任何东西。我对shell脚本完全陌生。我会尽力在今天和明天之间读一些东西。任何支持都会有所帮助。 –

+0

@RobertoKippins熟悉手册页,例如:'man 1 read'。 '1'通常可以省略,但可以确保您可以找到可执行文件。欲了解更多信息,请参阅'man man' :-)。另一个有趣的阅读是:http://mywiki.wooledge.org/Quotes和http://mywiki.wooledge.org/BashPitfalls不要害怕它,但评价者将它作为参考,只要你需要。此外,shellcheck是一个很好的工具和网站linting外壳脚本 – andlrc

回答

1

只是对二进制搜索方法的说明。使用大于/小于来检查用户提供的名称是否低于或高于数组中的当前名称是可行的,因为名称按字母顺序排列方便(这意味着赋予您此作业的人希望您利用此优势方便)。

验证码:

# 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:指定保留哪个字段(并因此存储到数组中)。

解释代码:

  1. 你可以认为你作为一个CSV文件的文本文件,除了:代替,作为分隔符。为此,我使用-d:。在文本文件中每行有两列(即两个字段)。
  2. 字段基本上等同于CSV文件中的列。这些字段由分隔符分隔,:。第一个字段包含学生的姓名,所以我用-f1来记录学生的姓名。第二个领域包含学生的成绩,所以我用-f2来捕捉学生的成绩。

完成!快乐编码

+0

这很好,马丁,谢谢你的所有细节和解释。从我所看到的有很多方法可以实现这一点,我一定会研究所有的评论,并尝试自己做。 –

+0

在bash中这样做肯定有很多方法。如果你计划自己回答这个问题,并且不再寻找来自StackOverflow的帮助,你应该做一些事情来表明你不是在寻找来自StackOverflow社区的答案。我希望这个答案有帮助:) –

+0

另外,顺便说一句(只是你知道)这个问题已被问到这个网站上。如果你想要一些更可能的方法,请参阅[这个问题](http://stackoverflow.com/q/22056855/5209610)。在我的回答中,我从技术上不提供*二进制*搜索方法,但我的答案肯定会给你一个好的开始。 –