Hier habe ich die meisten meiner Fehler behoben und danke Ihnen allen, anderen Ratschlägen bitte mit meinem Hash an dieser Stelle und wie kann ich jedes Wort löschen und setze das Wort und seine Häufigkeit in einen Hash, ohne die leeren Wörter. Ich denke mein Code macht seit jetzt.Perl Subroutinen
Antwort
So können Sie sich auf den Hauptteil des Algorithmus konzentrieren, wie wäre es mit der Eingabe von STDIN und der Ausgabe von STDOUT. Auf diese Weise gibt es kein Argument Überprüfung usw. Nur ein einfaches:
$ prog < words.txt
Alle brauchen Sie wirklich ein sehr einfacher Algorithmus:
- Lesen Sie eine Linie
- Split in Worte
- Bilanz eine Zählung des Wortes
- Wenn Sie fertig sind, die Zählungen anzuzeigen
Hier ist ein Beispielprogramm
#! /usr/bin/perl -w
use strict;
my (%data);
while (<STDIN>) {
chomp;
my(@words) = split(/\s+/);
foreach my $word (@words) {
if (!defined($data{$word})) {
$data{$word} = 0;
}
$data{$word}++;
}
}
foreach (sort(keys(%data))) {
print "$_: $data{$_}\n";
}
Sobald Sie dies verstehen und haben es in Ihrer Umgebung arbeiten, können Sie es erweitern können Ihren anderen Anforderungen gerecht zu werden:
- entfernen nicht-alphabetische Zeichen von jedem Wort
- Druck drei Ergebnisse pro Zeile
- Verwendung Ein- und Ausgabedateien
- setzten den Algorithmus in ein Unterprogramm
Ich wünschte, ich mache es jetzt richtig. –
Ich bin damit einverstanden, dass mit Daves Antwort beginnen wäre produktiver, aber wenn Sie in Ihren Fehlern interessiert sind, hier ist das, was ich sehe:
Sie den Rückgabewert von checkArgs zu einem skalaren Variablen zuweisen $ checkArgs, aber gibt einen Array-Wert zurück. Dies bedeutet, dass $ checkArgs nach diesem Aufruf immer 2 (die Größe des Arrays) enthält (weil das Programm abbricht, wenn die Anzahl der Argumente nicht 2 ist). Es ist nicht sehr schlecht, da Sie den Wert später nicht verwenden, aber warum brauchen Sie ihn in diesem Fall überhaupt?
Sie öffnen Dateien und schließen sie sofort, ohne von ihnen zu lesen. Macht keinen Sinn.
Statement
while (<>)
liest entweder von Standardausgabe oder aus allen Dateien in den Kommandozeilenargumenten. Die zweite Variante ist wie gewünscht, aber das zweite Argument ist die Ausgabedatei, nicht die Eingabe. Der Diamantoperator wird versuchen, auch davon zu lesen. Sie haben zwei Möglichkeiten: a) Verwenden Sie nur einen Dateinamen in den Befehlszeilenargumenten, lesen Sie die Datei mit <>, verwenden Sie die Standardausgabe für die Ausgabe und leiten Sie die Ausgabe in eine Datei in der Shell um; b) Verwenden Sie
while(<$file1>)
statt natürlich vor dem Schließen von Dateien. Option a) ist der traditionelle Unix- und Perl-Stil, aber b) bietet klareren Code für Anfänger.
Statements
return $ Wort;
und
return $str, $hash{$str};
Rückgabewerte auf den ersten Iterationen der Schleifen entsprechen, alle anderen Daten bleiben unbearbeitet. Im ersten Fall sollten Sie ein lokales Array erstellen, alle $ word darin speichern und das Array als Ganzes zurückgeben. Im zweiten Fall haben Sie bereits einen solchen lokalen% Hash, es reicht, diesen Hash zurückzugeben. In beiden Fällen müssen Sie die Rückgabewerte der Funktionen nicht auf Skalare, sondern auf ein Array und einen Hash entsprechend zuweisen. Jetzt verlieren Sie tatsächlich alle Daten.
Ich habe den Großteil des Codes bisher behoben. Ich freue mich über jede Rückmeldung, danke. –
Welche Tests/Debugging haben Sie selbst durchgeführt? Ich weiß, dass du neu in Perl bist, aber in _einer_ Sprache wird '' 'in der Mitte einer Schleife zurückkehren, was du willst? – Mort
Um genauer zu sein Ich bin total verloren mit wie man Liste der Wörter aus der Eingabedatei erstellen und Leerzeichen und Bindestriche als Trennzeichen. und das Sub gibt die Liste zurück. und für mein Hash möchte ich, dass es die Wörter und ihre Häufigkeit in einen Hash setzt. Vielen Dank für Ihre Antwort –
Sie öffnen die Dateien; du schließt die Dateien; Dann verwenden Sie 'while (<>)', um die Argumente zu verarbeiten, was bedeutet, dass Perl sowohl die Eingabedatei als auch die jetzt erstellte, aber leere Ausgabedatei liest. Ihre 'createList' gibt das erste Wort zurück - das scheint falsch zu sein. –