javascript(闭包)中的递归回溯

时间:2014-06-04 15:36:20

标签: javascript recursion closures

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

我已经让代码工作了,但是语法有点难看,因为为了避免带有闭包错误的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);

1 个答案:

答案 0 :(得分:1)

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

例如:

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

希望有所帮助。