【问题标题】:Recursive backtracking in javascript (closures)javascript中的递归回溯(闭包)
【发布时间】:2014-06-04 15:36:20
【问题描述】:

我正在尝试在 javascript 中实现递归回溯算法(确定单词是否为字谜)。粗略的想法是我置换不同字母的每个组合,然后将最终单词与单词表进行比较。

我已经让代码工作了,但是语法有点难看,因为为了避免带有闭包错误的 for 循环,我使用了一个自调用匿名函数,存储了该值,如果它是真的,返回以中断 for 循环。我只是想知道是否有更聪明的方法来实现代码,所以我不需要担心闭包?

var wordList = ['boats', 'horse', 'cow'];

var input = 'oastb';

function isAnagram(sofar, remaining) {

  if (remaining.length === 0) {
    console.log('returning: ' + (wordList.indexOf(sofar) !== -1))
    if (wordList.indexOf(sofar) !== -1) {
      console.log(sofar);
      return true;
    } else {
      return false;
    }
  } else {
     for (var i = 0; i < remaining.length; i++) {
      var found = (function(index) {
        if (isAnagram(sofar + remaining[index], remaining.substring(0, index) + remaining.substring(index + 1))) return true;
      })(i);

      if(found) return true;
    };    
  }

  return false;


}

isAnagram('', input);

【问题讨论】:

    标签: javascript recursion closures


    【解决方案1】:

    是的,有一种更简单的方法可以确定给定单词是否是单词列表的字谜。首先,我们需要normalize每个单词,以便每个字谜产生相同的唯一单词。

    例如:

    normalize("boats") = "abost";
    normalize("horse") = "ehors";
    normalize("cow")   = "cow";
    normalize("oastb") = "abost";
    

    事实证明,在 JavaScript 中实现这样一个函数非常简单:

    function normalize(word) {
        return word
            .split("") // convert the string into an array of characters
            .sort()    // sort the array of characters in lexicographic order
            .join(""); // convert the sorted array of characters into a string
    }
    

    接下来,我们创建一个函数,该函数获取给定的单词列表,对其进行规范化,并将它们添加到字典中,该字典将每个规范化的单词映射到其字谜列表。

    function dictionaryOf(words) {
        var dictionary = {};
    
        words.forEach(function (word) {
            var norm = normalize(word);
            if (dictionary.hasOwnProperty(norm))
                dictionary[norm].push(word);
            else dictionary[norm] = [word];
        });
    
        return dictionary;
    }
    

    然后,我们创建一个函数,当给定一个归一化单词到字谜和特定单词的字典时,返回该单词的字谜列表。

    function anagramsOf(dictionary, word) {
        var norm = normalize(word);
        return dictionary.hasOwnProperty(norm) ?
            dictionary[norm] : [];
    }
    

    最后,我们可以实现isAnagram函数如下:

    function isAnagram(dictionary, word) {
        return anagramsOf(dictionary, word).length > 0;
    }
    

    我们使用如下:

    var dictionary = dictionaryOf(["boats", "horse", "cow"]);
    
    alert(isAnagram(dictionary, "oastb"));
    

    把它们放在一起:

    var dictionary = dictionaryOf(["boats", "horse", "cow"]);
    
    alert(isAnagram(dictionary, "oastb"));
    
    function normalize(word) {
        return word.split("").sort().join("");
    }
    
    function dictionaryOf(words) {
        var dictionary = {};
    
        words.forEach(function (word) {
            var norm = normalize(word);
            if (dictionary.hasOwnProperty(norm))
                dictionary[norm].push(word);
            else dictionary[norm] = [word];
        });
    
        return dictionary;
    }
    
    function anagramsOf(dictionary, word) {
        var norm = normalize(word);
        return dictionary.hasOwnProperty(norm) ?
            dictionary[norm] : [];
    }
    
    function isAnagram(dictionary, word) {
        return anagramsOf(dictionary, word).length > 0;
    }

    希望对您有所帮助。

    【讨论】:

    • 谢谢,我完全没有想到这种方法。真正聪明的解决方案!
    猜你喜欢
    • 2018-10-08
    • 2021-12-28
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多