Implementierung eines Word-Chain-Checkers

Sep 07 2020

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 auf falseandere 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

10 AJNeufeld Sep 07 2020 at 23:22

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; 
    }
6 Doi9t Sep 07 2020 at 22:07

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 zuzuweisen ruth && 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.