使用数组javascript查找最长的字谜

使用数组javascript查找最长的字谜,javascript,arrays,algorithm,Javascript,Arrays,Algorithm,我试图在Javascript中找到最长的字谜。为此,我有一个包含10个字母的数组和一个包含每个单词的字典 我希望程序能测试所有可能的组合 我们从10(字母的数组长度)开始,检查它是否是一个字谜 如果没有,我们在最后移除字符,然后检查,如果没有,我们将移除的字符向左移动一个。。。当测试9个字母的整个组合时,我们测试8、7、6、5、4、3、2个字母 var-wordFound=''//找到的最长单词 var copyArr=[]//我不操作lettersChosen数组,所以我在copyArr中保存

我试图在Javascript中找到最长的字谜。为此,我有一个包含10个字母的数组和一个包含每个单词的字典

我希望程序能测试所有可能的组合

我们从10(字母的数组长度)开始,检查它是否是一个字谜 如果没有,我们在最后移除字符,然后检查,如果没有,我们将移除的字符向左移动一个。。。当测试9个字母的整个组合时,我们测试8、7、6、5、4、3、2个字母

var-wordFound=''//找到的最长单词
var copyArr=[]//我不操作lettersChosen数组,所以我在copyArr中保存了一个副本
var savedWord=[]//copyArr的副本,但我对此不确定
var lengthLetters=0//左数的长度
var lettersChosen=['A','S','V','T','S','E','A','M','N']//这是字母数组
函数isAnagram(stringA、stringB){
stringA=stringA.toLowerCase()。替换(/[\W\u]+/g,”);
stringB=stringB.toLowerCase()。替换(/[\W\u]+/g,”);
const stringASorted=stringA.split(“”.sort().join(“”);
常量stringBSorted=stringB.split(“”.sort().join(“”);
返回stringASorted==stringBSorted;
}
函数校验前置词(arr){
strLetters=''
对于(我在arr中)
strLetters=strLetters+arr[i]
for(文件中的变量i)
if(isAnagram(strleters,文件[i])){
wordFound=file[i]
返回真值
}
返回错误
}
函数getoneoflonglestword(){
lettersChosen.forEach(字母=>{
copyArr.push(字母)//我复制数组
})
var index=1//要删除的字母的索引
var countLetter=1//我必须删除多少字母
var position=copyArr.length-index//要删除的实际位置
var savedArray=[]//CopyArr的副本,但我不确定
var迭代=0//可能的组合总数
var test=checkForEachWord(copyArr)//我尝试使用10个字母
如果(测试==真)
return true//我找到了最长的单词
while(test==false){
copyArr.splice(位置,1)//我删除当前位置的字符
index++//更改要删除的字母
如果(index>copyArr.length+1){//如果我点击了第一个字符,那么从末尾重新启动
索引=1
countLetter++//再删除一个字母
}
console.log(copyArr+'|'+位置)
position=copyArr.length-index//根据数组字母的实际大小获取位置
test=checkForEachWord(copyArr)//测试字谜
copyArr=[]//重置数组
lettersChosen.forEach(letter=>{//重新创建数组
复印推送(信件)
})
}
返回true//找到单词
}
GetOneOfLongWord()
我的代码不是最优的,有很多方法可以改进它

事实上,我的输出有9个字母

copyArr | position
A,S,V,T,S,E,A,M | 8
A,S,V,T,S,E,M,N | 6
A,S,V,T,S,A,M,N | 5
A,S,V,T,E,A,M,N | 4
A,S,V,S,E,A,M,N | 3
A,S,T,S,E,A,M,N | 2
A,V,T,S,E,A,M,N | 1
S,V,T,S,E,A,M,N | 0
但不是用8个字母,我不知道如何用我的countLetter来测试所有的组合


非常感谢。

简短回答,将字典单词的排序版本放入a,然后执行a

回答得更长,因为你可能还没有遇到过这些问题

trie是一种数据结构,它在每一点上为您提供下一级trie的字符查找。您可以只使用空白对象作为trie。下面是一些简单的代码来添加一个单词

function add_to_trie (trie, word) {
    let letters = word.split('').sort();
    for (let i in letters) {
        let letter = letters[i];
        if (! trie[letter]) {
            trie[letter] = {};
        }
        trie = trie[letter];
    }
    trie['final'] = word;
}
A*搜索仅仅意味着我们有一个优先级队列,它为我们提供了下一步的最佳选择。我不需要实现自己的优先级队列,而只需要使用现有的优先级队列。它返回尽可能低的优先级。所以我会优先使用最长的词,如果有一个并列词,那么就用我们最远的词。这里是一个实现

import FlatQueue from "flatqueue";

function longest_word_from (trie, letters) {
    let sorted_letters = letters.sort();
    let queue = new FlatQueue();
    // Entries will be [position, current_length, this_trie]
    // We prioritize the longest word length first, then the
    // number of characters.  Since we get the minimum first,
    // we make priorities negative numbers.
    queue.push([0, 0, trie], - (letters.length ** 2));

    while (0 < queue.length) {
        let entry = queue.pop();

        let position = entry[0];
        let word_length = entry[1];
        let this_trie = entry[2];

        if (position == letters.length) {
            if ('final' in this_trie) {
                return this_trie['final'];
            }
        }
        else {
            if (letters[position] in this_trie) {
                queue.push(
                    [
                        position + 1, // Advance the position
                        word_length + 1, // We added a letter
                        this_trie[letters[position]] // And the sub-trie after that letter
                    ],
                    - letters.length * (
                        letters.length + position - word_length
                      ) - word_length - 1
                );
            }

            queue.push(
                [
                    position + 1, // Advance the position
                    word_length,  // We didn't add a a letter
                    this_trie // And stayed at the same position.
                ],

                - letters.length * (
                    letters.length + position - word_length - 1
                  ) - word_length
            );
        }
    }
    return null;
}

如果你有一本很长的字典,那么将字典加载到trie中是你大部分时间的事情。但一旦你做到了这一点,你就可以用不同的字母一次又一次地调用它,并很快得到答案。

如果你有一本字典,上面有字母排序的单词,那么就很容易找到字谜。例如,字典{'ACER':['ACRE','CARE','RACE']}和输入'CREA',只需对输入进行排序=>'ACER',然后在字典中查找即可。(顺便说一句combinaison=composition)我想找到最长的字谜,所以我必须在找到一个字谜的同时测试所有的字谜。我真的不明白你的建议。你可以用字母的任何子集来做一个字谜吗?也许你可以给出一些具体的例子——比如输入和预期的输出,来演示问题是什么,或者你想改进的
区域
…你只是在寻找单个单词的字谜,比如
NIGHT
东西
?或者你会选择多词的,比如乔治·布什/
他讨厌戈尔
?非常感谢你的回答。它工作得很好,我昨天发现了另一个算法,但它太长了(因为字典文件太大),你的更快。@Cobrabraisé如果你需要更快,你可以按频率而不是按字母顺序对字母排序。我用字典测试了你的代码,速度很快。但是谢谢你分享这个,如果我以后需要的话,我会把它放在腋下
let file = ['foo', 'bar', 'baz', 'floop'];
let letters = 'fleaopo'.split('')

let this_trie = {};
for (var i in file) {
    add_to_trie(this_trie, file[i]);
}

console.log(longest_word_from(this_trie, letters));