2016-06-09 12 views
2

Ich brauche eine Idee zu tun, wie dieses Forschungsprojekt abzuschließen:Bash-Skript binäre Suche und Speichern von Werten in einem Array

ein Bash-Skript schreiben eine binäre Suche zu tun. Lesen Sie die Namen und Noten von Schülern aus einer Datei in ein Array.
Fragen Sie den Benutzer nach einem Schülernamen. Suchen Sie den Namen im Array und zeigen Sie die Note an. Wenn der Schüler nicht existiert, drucken Sie eine Nachricht, die besagt, dass.

Die Daten in der Datei sind unter:

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

'lesen -r my_var' kann lesen von stdin oder tty:' lesen -r my_var andlrc

+0

Ich habe noch nichts versucht. Ich bin total grün für Shell-Skripte. Ich werde versuchen, einige Dinge zwischen heute und morgen zu lesen. Jede Unterstützung wird hilfreich sein. –

+0

@RobertoKippins Machen Sie sich mit den Manpages vertraut, zum Beispiel: 'man 1 read'. Die "1" kann normalerweise weggelassen werden, stellt aber sicher, dass Sie ausführbare Dateien finden. Für weitere Informationen siehe 'Mann Mann' :-). Eine weitere interessante Lektüre ist: http://mywiki.wooledge.org/Quotes und http://mywiki.wooledge.org/BashPitfalls Hab keine Angst davor, aber rater benutze es als Referenz, wann immer du es brauchst.Auch Shellcheck ist ein gutes Tool und eine gute Webseite um linting Shell Skripte zu erstellen. – andlrc

Antwort

1

Nur eine Notiz über den binären Suchansatz. Mit "größer als" oder "kleiner als" können Sie überprüfen, ob der angegebene Name des Benutzers unterhalb oder oberhalb des aktuellen Namens im Array liegt, da die Namen in alphabetischer Reihenfolge stehen (dh die Person, die Ihnen diese Aufgabe erteilt hat) Bequemlichkeit).

Der Code:

# 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 

Wenn Sie ein gut lesbarer Ansatz sein nicht die binäre Suche finden, wie ich, dann würde ich empfehlen, ein for-Schleife:

# 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 

Für den cut Befehl, wenn Sie nicht vertraut sind ...

-d: gibt das Trennzeichen in der gegebenen Text verwendet Datei.

-f: Gibt an, welches Feld beibehalten (und somit in das Array gespeichert werden soll).

Erklärung der Code:

  1. Sie der Textdatei denken, Sie können als CSV-Datei haben, mit Ausnahme von : statt , als Trennzeichen verwendet. Aus diesem Grund verwende ich -d:. Es gibt zwei Spalten (d. H. Zwei Felder) pro Zeile in Ihrer Textdatei.
  2. Ein Feld entspricht im Wesentlichen einer Spalte in einer CSV-Datei. Die Felder sind durch das Trennzeichen : getrennt. Das erste Feld enthält den Namen des Schülers, also habe ich -f1 verwendet, um die Namen der Schüler zu erfassen. Das zweite Feld enthält die Note des Schülers, also habe ich -f2 verwendet, um die Noten der Schüler zu erfassen.

Fertig! Happy coding

+0

Das hat gut funktioniert Martin, und danke für alle Details und Erklärungen. Von dem, was ich sehe, gibt es viele Möglichkeiten, dies zu erreichen, und ich werde definitiv alle Kommentare studieren und versuchen, es alleine zu machen. –

+0

Es gibt definitiv einige Möglichkeiten, dies in bash zu tun. Wenn Sie vorhaben, diese Frage selbst zu beantworten und nicht mehr Hilfe von StackOverflow suchen, sollten Sie etwas tun, um anzuzeigen, dass Sie nicht nach einer Antwort von der StackOverflow-Community suchen. Ich hoffe diese Antwort hilft :) –

+0

Übrigens (übrigens, damit Sie wissen) wurde diese Frage bereits auf dieser Seite gestellt. Siehe [diese Frage] (http://stackoverflow.com/q/22056855/5209610), wenn Sie weitere mögliche Ansätze wünschen. In meiner Antwort stelle ich technisch keinen * binären * Suchansatz zur Verfügung, obwohl meine Antwort definitiv einen guten Anfang geben sollte. –