我正在尝试在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);
答案 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;
}
希望有所帮助。