javascript哈希表值读取不正确

时间:2016-09-20 23:39:41

标签: javascript

请看这个JSFiddle:https://jsfiddle.net/nu69kxyq/

这个JS接受输入文本文件,每行包含一个单词。 JS函数找到最长和第二长的复合词(仅由文件中的其他词组成)和这些复合词的总数。

这是我正在使用的确切输入:

cat
cats
catsdogcats
dog
dogcatsdog
hippopotamuses
rat
ratcatdogcat

输出应为:

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

复合词的总数是3,因为catdogcats,dogcatsdog,ratcatdogcat。

我首先接受所有单词,然后在wordsList中对其进行排序。然后我在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;
};

问题出在isConcat,当我检查wordDict[prefix]以查看密钥的值是否为真时,它始终为false。即使它应该是真的!我尝试单步执行代码,当'word'键的键值为'true'时,if (wordDict[prefix] === true)语句仍然不执行,因为它认为它是错误的。使用data.split("\n");,我能够读取文本文件并将其放入数组中。没问题。出了什么问题?

注意:我尝试使用var list = data.match(/\w+/g);代替var list = data.split("\n");将所有字​​母数字字符匹配为单词,而不是按新行分割它们,并且函数有效(wordDict [prefix]按预期工作)。但是当我传入超过150,000个文本单词的文本文件时,这个正则表达式会跳过一些单词。我想我需要使用data.split("\n")。这里出了什么问题?

1 个答案:

答案 0 :(得分:1)

这是一个isConcat的工作实现,它不是递归的,因此不会出现堆栈溢出错误的问题:

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;
}

它基本上做同样的事情,除了它循环/重启而不是递归。 请注意,这不仅会匹配复合词,还会匹配与列表中的单词完全匹配的单词(只有一个单词的复合词)。