Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正则表达式(Javascript)-获取一个加扰的单词并找到一个未加扰的匹配项_Javascript_Regex - Fatal编程技术网

正则表达式(Javascript)-获取一个加扰的单词并找到一个未加扰的匹配项

正则表达式(Javascript)-获取一个加扰的单词并找到一个未加扰的匹配项,javascript,regex,Javascript,Regex,我有一个英语词典中所有单词的列表(270000多个单词),存储在一个名为theList的变量中。 我有一个加扰的单词word,我想通过匹配单词列表来解读它。 起初,我认为下面的代码可以做到这一点,但效果不太好 var theList; // Contains all the words in the English dictionary. var word = "iexospensr"; // The word I want to unscramble. var matches = word

我有一个英语词典中所有单词的列表(270000多个单词),存储在一个名为
theList
的变量中。 我有一个加扰的单词
word
,我想通过匹配单词列表来解读它。 起初,我认为下面的代码可以做到这一点,但效果不太好

var theList; // Contains all the words in the English dictionary.

var word = "iexospensr"; // The word I want to unscramble.

var matches = word.match(new RegExp("^["+word+"]{"+word.length+"}$", "gim"));
我本以为“表达式”是解读的结果,但我得到了更多的结果(如下所列)

怪诞,表现者,表情,讽刺,等孢子,非人格,非十字架,爱管闲事,开放,压迫,压迫者,华丽,养老金,养老金,养老金领取者,佩珀罗尼斯,波斯人,人格,皮皮皮尼斯,皮皮西尼斯,穷人,穷人,穷人,占有,占有,占有,预暴露,预暴露,预暴露,先验,普里西尼,财产,适当性、复吸、抑制、抑制、抑制、利血平、反应、反应、成熟、罗皮内斯、罗西内斯、宁静、性感、六便士、剪彩、酸痛、喷丝女

也许,如果我能找到一个方法来告诉正则表达式在字符串<代码>单词< /代码>中的每一个字母一次,而不考虑字母的顺序。所以最终的结果将是这些字母的组合数组,而不是排列(我现在看到的)

任何帮助都将不胜感激


编辑: 我认为应该走的路是: 1.查找加扰词的所有组合 2.将它们与单词列表匹配以检查有效性

如果您有更好的解决方案(性能方面),它会有所帮助


这个问题的最佳解决方案似乎是按字母表重新排列字谜,以及整个单词列表,并将单词与列表中的每个项目进行匹配

代码如下:

    var textList; // the entire dictionary
    var list = textList.match(/^.*$/gim);
    var sortedList = [];
    list.forEach(function(element, index, array) {
        sortedList[index] = element.split("").sort().join("");
    });

    function unscramble(word)
    {
        word = word.toUpperCase().split("").sort().join("");
        var matches = [];
        for (var i = 0; i < list.length; i++) {
            if (word.indexOf(sortedList[i]) >= 0) {
                if (!matches[list[i].length])
                    matches[list[i].length] = [];
                matches[list[i].length].push(list[i]);
            }
        }
        return matches;
    }
var textList;//整本字典
var list=textList.match(/^.*$/gim);
var-sortedList=[];
forEach(函数(元素、索引、数组){
sortedList[索引]=元素.split(“”).sort().join(“”);
});
功能解读(word)
{
word=word.toUpperCase().split(“”).sort().join(“”);
var匹配=[];
对于(变量i=0;i=0){
如果(!匹配[list[i].length])
匹配项[列表[i]。长度]=[];
匹配[list[i].length].push(list[i]);
}
}
返回比赛;
}

我不知道正则表达式是否是这项工作的最佳工具。你正在构建的正则表达式最终将成为

"^[iexospensr]{10}$"
它匹配由字符类中的任何字母组成的任何10个字母的单词
[iexospensr]

也许,如果我能找到一种方法来告诉正则表达式,不管字符串的顺序如何,只考虑字符串中的每一个字母。


您可以使用
word.length
不同的正则表达式来实现这一点,但有些字母会重复。如果你对拼凑的单词中的字母进行排序,然后搜索每个字母重复次数正确的单词,你会更接近。例如,两个e、两个s、一个x等等。

我认为更好的方法不会使用正则表达式。取而代之的是,它将根据您的加扰单词测试列表中的每个成员,方法是遍历单词的字符,并查看该字符是否存在于列表中的单词中。每次找到一个字符时,它都可以将该字符标记为“已使用”

这里有一些东西可以将角色位置标记为“已使用”:


正则表达式虽然功能强大,但并不是万能的解决方案

在这样的情况下,最好构建自己的解决方案:首先删除所有与所需长度不匹配的单词,然后开始比较字母


根据字典的长度,您可以构建不同的优化。

这里有一个想法。构造初始查找数据将很慢,但查找匹配项应该很简单。但是,您应该只构建一次字典并加载它!每次重新计算都是浪费时间

  • 我假设您只使用拉丁字母表(即英文书写),所有内容都不区分大小写,并且您不使用数字…等等。所以你只有A-Z个字符

  • 对于字典中的每个单词,根据每个字母出现的次数构建一个“哈希”。散列数组将有26个位置。每个位置将记录遇到该位置的特定字符的次数。(例如,A位于第一个数组位置/索引0;Z位于第26个/索引25)
    要稍微作弊,可以将结果存储为一对字符串。如果有的话,很少有单词的一个字母有9个重复,所以每个字母只有一个“数字”就可以了。例如:“该”变为“00001000000000000000000”;“帽子”变为“100000000001000000000”;“该”变为“10000002000000”

  • 加载预计算字典。将哈希值用作键值对中的键,并将集合用作值。将具有相同关键字的每个单词附加到该关键字集合的末尾

  • 对加扰字执行相同的哈希算法,并查找密钥。输出键引用的集合

  • 编辑1: 如果预先构建一个字典是不可行的,那么使用一个变体,创建一个以字母为键的关联数组/字典,找到它的次数作为值。在计算这个之前,比较长度,如果字符串的长度不同,那么不要费心比较,因为你知道它们不匹配。计算源(加扰)和目标(可能匹配)的这些数组后,比较关联数组中的键和值

    编辑2: 按照与上面相同的思路,对源和目标字符串中的字符进行排序
    function checkUsed(o, which) {
    if (o[which] != null) {
      o[which] = 1;
      return false;
      }
    return true;
    }
    
    
    var usedMap = [];
    
    if (checkUsed(usedMap, 5) == false) {
     ...
     }
    
    //WARNING, untested code
    
    alphabet = 'qwertyuiopasdfghjklzxcvbnm';
    function empty_frequences(){
        var freqs = {};
        var i=;
        for(i=0; i<alphabet.length; i++){
            freqs[alphabet[i]] = 0;
        }
        return freqs;
    }
    
    function frequences(str){
        var freqs = empty_frequences();
        var i;
        for(i=0; i<str.length; i++){
            freqs[str[i]] += 1;
        }
    }
    
    function matcher(word){
         //returns a function that matchs against this word
         var word_freqs = frequences(word);
         function do_the_match(word2){
             var freqs2 = frequences(word2);
             var i, c;
             for(i=0; i<alphabet.length; i++){
                 c = alphabet[i]
                 if(freqs[c] > freqs2[c]){return false;}
                 //change > to != to allow only strict anagrams
             }
             return true;
         }
         return do_the_match;
     }
    
     function main(word, dict){
         var mf = matcher(word);
         var i, matcheds = [];
         for(i=0; i<dict.length; i++){
             if(mf(dict[i])){ matcheds.push(dict[i]); }
         }
         return matcheds;
     }
    
    > var words = 'exceptional extraordinary retinas retains retsina antsier nastier retrains starfish';
    > words.match(/\b([aeinrst])(?!\1)([aeinrst])(?!\1|\2)([aeinrst])(?!\1|\2|\3)([aeinrst])(?!\1|\2|\3|\4)([aeinrst])(?!\1|\2|\3|\4|\5)([aeinrst])(?!\1|\2|\3|\4|\5|\6)([aeinrst])\b/ig)
    [ 'retinas', 'retains', 'retsina', 'antsier', 'nastier' ]