Implementierung eines Word-Chain-Checkers
Dies ist die Webübung 3.1.45. aus dem Buch Informatik Ein interdisziplinärer Ansatz von Sedgewick & Wayne:
Schreiben Sie ein Programm, das eine Liste von Wörtern aus der Befehlszeile einliest und druckt,
truewenn sie eine Wortkette bilden und auffalseandere Weise. In einer Wortkette müssen sich benachbarte Wörter in genau einem Buchstaben unterscheiden, z. B. HEAL, HEAD, DEAD, DEED, DEER, BEER.
Hier ist mein Programm:
public class WordChainChecker
{
public static boolean checkWordCouple(String word1, String word2)
{
int counter = 0;
int wordLength = word1.length();
for (int i = 0; i < wordLength; i++)
{
if (word1.charAt(i) != word2.charAt(i)) counter++;
}
if (counter > 1) return false;
else return true;
}
public static void main(String[] args)
{
String word1 = StdIn.readString();
String word2 = StdIn.readString();
boolean truth = true && checkWordCouple(word1,word2);
while (!StdIn.isEmpty())
{
word1 = StdIn.readString();
truth = truth && checkWordCouple(word1,word2);
word2 = word1;
}
System.out.println(truth);
}
}
StdIn ist eine einfache API, die von den Autoren des Buches geschrieben wurde. Ich habe mein Programm überprüft und es funktioniert.
Gibt es eine Möglichkeit, mein Programm zu verbessern?
Danke für Ihre Aufmerksamkeit.
Antworten
Bedarf
Anzahl der Wörter
Haben Sie garantiert mindestens 2 Wörter? In diesem Fall können Sie Ihre Schleife vereinfachen, indem Sie den ersten Lesevorgang entfernen. Die Schleife kümmert sich um das zweite und die folgenden Wörter:
String word2 = StdIn.readString();
boolean truth = true;
while (!StdIn.isEmpty())
{
String word1 = StdIn.readString();
truth = truth && checkWordCouple(word1,word2);
word2 = word1;
}
Obwohl jetzt, wenn ein einzelnes Wort gegeben wird, wird es produzieren true. Dies kann eine Verbesserung sein, aber Sie müssen die genauen Anforderungen überprüfen, um sicherzugehen.
Wortlänge
I HEAD, HEAL, TEA, TOeine Wortkette? Ihr Programm sagt es ist!
Was HEADist HEALmit HEALTHY? Diese Eingabe führt zum Absturz Ihres Programms!
Ihr Programm sollte nicht übereinstimmende Wortlängen verarbeiten, es sei denn, die Problemstellung garantiert, dass alle Eingaben dieselbe Länge haben.
Anzahl der Unterschiede
Die Problembeschreibung lautet:
In einer Wortkette müssen sich benachbarte Wörter in genau einem Buchstaben unterscheiden
aber HEAD, HEAD, HEAD, HEADwird als „wahr“ berichtet. Offensichtlich counter > 1ist nicht die richtige "falsche" Bedingung. Wenn Sie den Vorschlag von Doi9t ausleihen und ihn weiter verbessern, würde die richtige Zeile lauten:
return counter == 1;
Selbstdokumentierender Code
Sie lesen word1, dann word2, und vergleichen Sie die ersten in den zweiten (nennen wir das „Vorwärts“), dann ein drittes in gelesen word1, und die dritte auf den zweiten (Vergleich in der „Rückwärts“ -Richtung) vergleichen. Sie testen auf einen Unterschied, damit es funktioniert, aber was ist, wenn Sie nach einem zusätzlichen Zeichen suchen? Wenn Sie die Wortreihenfolge umkehren, testen Sie tatsächlich die Zeichenentfernung!
Statt word1& word2, vielleicht previous_wordund next_wordwürde die Dinge klarer helfen.
String previous_word = StdIn.readString();
boolean truth = true;
while (!StdIn.isEmpty())
{
String next_word = StdIn.readString();
truth = truth && checkWordCouple(previous_word, next_word);
previous_word = next_word;
}
Ich habe einige Vorschläge für Ihren Code.
Vereinfachen Sie die booleschen Bedingungen.
Wenn Sie beide zurückgeben trueund falsevon einer Bedingung umgeben sind, wissen Sie im Allgemeinen, dass Sie die Logik des Ausdrucks umgestalten können.
if (counter > 1) return false;
else return true;
kann geändert werden in
return counter <= 1;
Durch Ändern des Bereichs können wir den Zustand verkürzen.
boolean truth = true && checkWordCouple(word1,word2);
kann geändert werden in
boolean truth = checkWordCouple(word1,word2);
Der andOperator ist nutzlos ( true && false == falseund true && true == true) und entspricht einem einzelnen Booleschen Wert, der von der checkWordCoupleMethode angegeben wird.
Verwenden Sie nach Möglichkeit den vereinfachten Operator.
BEARBEITEN: Wie in den Kommentaren dieser Antwort angegeben, wird die Verwendung des Bitwise AND-Zuweisungsoperators in diesem Fall nicht empfohlen.
Java bietet Ihnen viele Operatoren, mit denen Sie mehrere Operationen ausführen können.
In Ihrem Fall können Sie das
Bitwise AND assignment operator(&=) verwenden, anstatt den Booleschen Wert jedes Mal mit dem Ergebnis von neu zuzuweisenruth && checkWordCouple(word1,word2).java truth = truth && checkWordCouple(word1,word2);in
java truth &= checkWordCouple(word1,word2);Dieser Operator weist sich das Ergebnis des zu
previous value && current.