bash脚本在数组中进行二进制搜索和存储值

时间:2016-06-09 18:59:53

标签: 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

1 个答案:

答案 0 :(得分: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来获取学生的成绩。
  3. 完成!快乐的编码