2016-09-20 2 views
0

Betrachten Sie bitte dieses JSFiddle: https://jsfiddle.net/nu69kxyq/Javascript-Hash-Tabellenwerte lesen falsch

Diese JS nimmt in Eingabetextdatei aus einem Wort bestehen jede Zeile. Die JS-Funktion findet das längste und zweitlängste COMPOUND-Wort (bestehend aus nur anderen Wörtern in der Datei) und die Gesamtanzahl dieser zusammengesetzten Wörter.

Dies ist die genaue Eingabe Ich verwende:

cat 
cats 
catsdogcats 
dog 
dogcatsdog 
hippopotamuses 
rat 
ratcatdogcat 

Die Ausgabe sollte:

ratcatdogcat <-- longest compound word (12 characters) 
catsdogcats <-- second longest compound word (11 characters) 
3 <-- total number of compound words in a file 

Gesamtzahl der zusammengesetzten Wörtern ist 3, weil catsdogcats, dogcatsdog, ratcatdogcat.

Ich nehme zuerst alle Wörter dann sortiere es in wordsList. Dann erstelle ich eine Hash-Tabelle von Wörtern als Referenz (überprüfen für zusammengesetzte Wörter) in wordDict:

var wordsList = list.sort(function(a, b) { 
    return a.length - b.length; //sort words by length ascending 
}); 

var wordDict = list.reduce(function(words, value, index) { //hash table from text file data 
    words[value] = true; 
    return words; 
},{}); 

var isConcat = function(word) { 
    for (var i = word.length; i > -1; i--){ 
    var prefix = word.slice(0,i); 
    var suffix = word.slice(i, word.length); 
    if (wordDict[prefix] === true){ //????? THIS IS ALWAYS FALSE EVEN WHEN THE KEY'S VALUE IS TRUE!!! 
     if (suffix.length === 0) { 
     return true; //all suffix are prefixes. word is concatenated. 
     } 
    return isConcat(suffix); //continue breaking remaining suffix into prefix if possible 
    } 
    } 
    return false; 
}; 

Das Problem ist in isConcat, wenn ich gegen wordDict[prefix] überprüfen, um zu sehen, ob Schlüssel den Wert wahr ist, es ist immer falsch . Auch wenn es wahr sein sollte! Ich habe versucht, durch den Code zu gehen, und wenn der Schlüsselwert 'wahr' für den 'Wort'-Schlüssel ist, wird die if (wordDict[prefix] === true)-Anweisung immer noch nicht ausgeführt, weil sie denkt, dass sie falsch ist. Unter Verwendung data.split("\n"); kann ich Textdatei lesen und sie in Reihe setzen. Keine Probleme dort. Was läuft also falsch?

Hinweis: Ich habe versucht var list = data.match(/\w+/g); anstelle von var list = data.split("\n"); zu verwenden, um alle alphanumerischen Zeichen als Wörter zu vergleichen, statt sie durch neue Zeile zu teilen, und die Funktion funktionierte (WordDict [Präfix] arbeitete wie erwartet). ABER diese Regex überspringt einige Wörter, wenn ich eine Textdatei von über 150.000 Textwörtern übergebe. Ich denke, ich muss data.split("\n") verwenden. Was läuft hier falsch? Hier

+0

Eigenschaften von Objekten in JavaScript können nicht wirklich nach Präfix gesucht werden, wenn Sie das tun. Zum Beispiel wird 'obj [" foo "]' nicht mit 'obj [" foobar "]' übereinstimmen. Ich habe noch nicht den ganzen Code durchgesehen, aber ich habe gemerkt, dass du 'obj [prefix]' – vlaz

+0

Nein, der Code teilt das Wort in zwei bei jedem Zeichen auf und checkt, das ist also nicht das Problem – qxz

+0

@RJK Hast du Setzen Sie einige 'console.log's um zu sehen, was die Werte von' wordDict', 'prefix' und' suffix' sind? – qxz

Antwort

1

ist eine funktionierende Implementierung von isConcat, die nicht rekursiv ist, und wird daher nicht hat Probleme mit Stack-Überlauf-Fehler:

function isConcat(word) { 
    for (var i = word.length; i >= 0; i--) { 
    var prefix = word.slice(0, i); 
    var suffix = word.slice(i); 
    if (wordDict[prefix]) { 
     if (suffix.length === 0) { 
     return true; // all suffix are prefixes. word is concatenated. 
     } else { 
     // "restart" with suffix as the word 
     word = suffix; 
     i = word.length+1; 
     } 
    } 
    } 
    return false; 
} 

es im Wesentlichen nicht die gleichen, außer es Schleifen/Neustart statt rekursiv. Beachten Sie, dass damit nicht nur zusammengesetzte Wörter abgeglichen werden, sondern auch Wörter, die exakt mit einem Wort aus der Liste übereinstimmen (eine Verbindung aus nur einem Wort).

+0

Ich verstehe. Wenn ich versuche, im Browser zu testen, scheint es zu hängen und die Seite reagiert nicht mehr. Denkst du, das liegt daran, dass wir auch genau ein Wort zusammenbringen? – RJK

+0

können wir etwas tun, wie 'if (Wort beginnt mit Suffix)' anstelle von 'Wort = Suffix' – RJK

+0

Wenn Sie eine ausreichend große Eingabe verwenden, könnte es" hängen "nur von der Bearbeitungszeit. Sie können ['string.startsWith (Präfix)'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) verwenden, um zu prüfen, ob eine Zeichenfolge mit einer anderen beginnt . – qxz