Heim  >  Artikel  >  ProjectEuler Frage 17: Ich habe diese Codezeile geändert und meine Antwort hat sich drastisch geändert, obwohl ich dachte, dass es funktionieren sollte

ProjectEuler Frage 17: Ich habe diese Codezeile geändert und meine Antwort hat sich drastisch geändert, obwohl ich dachte, dass es funktionieren sollte

WBOY
WBOYnach vorne
2024-02-13 20:51:08872Durchsuche

php-Editor Apple ist in ProjectEuler-Ausgabe 17 auf eine interessante Situation gestoßen. Nachdem er eine Codezeile geändert hatte, stellte er fest, dass sich die Antwort dramatisch änderte, obwohl er der Meinung war, dass der Code einwandfrei funktionieren sollte. Diese Frage weckte seine Neugier und er begann, die Gründe zu erforschen und nach Lösungen zu suchen. Diese Geschichte ist voller Herausforderungen und Gedanken und lässt die Leute gespannt auf die Antwort des Herausgebers sein.

Frageninhalt

Ich arbeite an der Projekt-Euler-Frage 17. Ich sollte ein Programm schreiben, um die Gesamtzahl der Zeichen in einer geschriebenen Zahl von 1 bis 1000 zu zählen. Sie ignorieren Leerzeichen und Bindestriche. Laut Problembeschreibung enthalten Hunderte von Zahlen ein „und“ (dreihundertzweiundvierzig). Mein Code funktioniert in den meisten Fällen, außer bei Vielfachen von 100 (wenn er die zusätzliche „Summe“ berechnet). Zählen Sie beispielsweise 600 als „sechshundertund“. Dies führte dazu, dass meine Antwort von 27 (3 von 100 Ziffern) abwich. Das ist fast die richtige Lösung:

string[] nums = {"",
                 "one",
                 "two",
                 "three",
                 "four",
                 "five",
                 "six",
                 "seven",
                 "eight",
                 "nine",
                 "ten",
                 "eleven",
                 "twelve",
                 "thirteen",
                 "fourteen",
                 "fifteen",
                 "sixteen",
                 "seventeen",
                 "eighteen",
                  "nineteen"};
string[] ten = {"",
                "",
                "twenty",
                "thirty",
                "forty",
                "fifty",
                "sixty",
                "seventy",
                "eighty",
                "ninety"};
int sum = 0;
map<integer, integer> ones = new hashmap<>();
map<integer, integer> teens = new hashmap<>();
map<integer, integer> tens = new hashmap<>();
for (int i = 0; i < 10; i++) {
    ones.put(i, nums[i].length());
}
for (int i = 10; i < nums.length; i++) {
    teens.put(i, nums[i].length());
}
for (int i = 0; i < ten.length; i++) {
    tens.put(i * 10, ten[i].length());
}
for (int i = 1; i < 1000; i++) {
    int num = 0;
    int n = i % 100;
    if (n > 19 || n < 10) {
        num += ones.get(n % 10);
        num += tens.get(n - n % 10);
    }
    else {
        num += teens.get(n);
    }
    num += i > 99 ? "hundredand".length() : 0;
    num += ones.get(i / 100);
    system.out.println(num + " " + i);
    sum += num;
}
sum += ("onethousand").length();
// actual is 21124
system.out.println(sum);

Dies führt zu einer Ausgabe von 21151, die sich um 27 von der erwarteten Ausgabe von 21124 unterscheidet. Die Variable num wird für Debugging-Zwecke verwendet.

Ich habe versucht, eine der Zeilen der Schleife zu ändern und eine zusätzliche Anweisung hinzugefügt:

num += i>99 ? "hundred".length() : 0;
num += i%100==0 ? 3 : 0;

Nachdem diese aktualisierte Version ausgeführt wurde, lautet die Ausgabe 18487. Ich bin mir nicht sicher, warum dieser Unterschied so auffällig ist und würde gerne verstehen, woher das kommt. Ich dachte zuerst, es läge am ternären Operator, da meine Kenntnisse darüber begrenzt sind. Auch alle Vorschläge, den Code effizienter zu gestalten, sind willkommen. Ich wollte vor dem Drucken die Summe 27 eingeben, aber ich finde, das ist ein bisschen Betrug :). Danke!

Problemumgehung

Wie andere in Kommentaren zu Ihrer Frage gesagt haben, besteht Ihr Problem darin, wie Ihr Code mit Zahlen umgeht, die ein Vielfaches von 100 sind. Man addiert immer hundert und nie nur hundertum>. Tatsächlich haben Sie sich in Ihrer Frage selbst angegeben:

Im folgenden Code verwende ich eine explizite if-Anweisung – anstelle des ternären Operators – weil ich glaube, dass der Code dadurch beim Lesen leichter verständlich ist. Bitte beachten Sie, dass dies die einzige Änderung ist, die ich an dem in Ihrer Frage veröffentlichten Code vorgenommen habe.

import java.util.hashmap;
import java.util.map;

public class myclass {
    public static void main(string args[]) {
        string[] nums = {"",
                         "one",
                         "two",
                         "three",
                         "four",
                         "five",
                         "six",
                         "seven",
                         "eight",
                         "nine",
                         "ten",
                         "eleven",
                         "twelve",
                         "thirteen",
                         "fourteen",
                         "fifteen",
                         "sixteen",
                         "seventeen",
                         "eighteen",
                         "nineteen"};
        string[] ten = {"",
                        "",
                        "twenty",
                        "thirty",
                        "forty",
                        "fifty",
                        "sixty",
                        "seventy",
                        "eighty",
                        "ninety"};
        int sum = 0;
        map<integer, integer> ones = new hashmap<>();
        map<integer, integer> teens = new hashmap<>();
        map<integer, integer> tens = new hashmap<>();
        for (int i = 0; i < 10; i++) {
            ones.put(i, nums[i].length());
        }
        for (int i = 10; i < nums.length; i++) {
            teens.put(i, nums[i].length());
        }
        for (int i = 0; i < ten.length; i++) {
            tens.put(i * 10, ten[i].length());
        }
        for (int i = 1; i < 1000; i++) {
            int num = 0;
            int n = i % 100;
            if (n > 19 || n < 10) {
                num += ones.get(n % 10);
                num += tens.get(n - n % 10);
            }
            else {
                num += teens.get(n);
            }
            if (i > 99) {
                num += n == 0 ? "hundred".length() : "hundredand".length();
            }
            num += ones.get(i / 100);
            sum += num;
//            system.out.printf("%2d %3d %5d%n", num, i, sum);
        }
        sum += ("onethousand").length();
        // actual is 21124
        system.out.println(sum);
    }
}

Wenn ich den obigen Code ausführe, erhalte ich die folgenden Ergebnisse:

21124

Im Code Ihrer Frage haben Sie (in den Codekommentaren) geschrieben, dass dies die erwartete Antwort ist.

Das obige ist der detaillierte Inhalt vonProjectEuler Frage 17: Ich habe diese Codezeile geändert und meine Antwort hat sich drastisch geändert, obwohl ich dachte, dass es funktionieren sollte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen