关于模糊查询的算法,是不是除了内存换取效率以外,没有更好的算法了

感谢建议,我再多研究一下

感谢您的建议,我感觉这个方法确实很好。
我现在的需求是,比如 “我没有带地图呀”,这7个字,玩家输入其中每一段字都要返回这句话,比如,我,没,有,带,地,图,呀。或者,我没,我没有,我没有带,或者,没有,没有带,等等。这个组合实在是太多了,已经不能用穷举来解决这个问题了。如果用一个字或者一段字来关联一个结果,这个量实在是太大了。我其实希望,能动态存储这些数据。

只有一个字的时候,直接用字的Unicode做数组下标索引原字符串ID列表最快。最小的Unicode对齐到下标0,可以稍微省一点空间。
字多的时候可以考虑在第一层的基础上用Boyer-Moore字符串查找算法(把第一个字对应的字符串看成一篇文章)。

字典树层级越多,空间浪费越多。但是如果是静态数据可以离线压缩空间的话,我觉得是运行时时间和空间最优的。

感谢提供的思路,我自己写的BM查找算法,慢多了,10万次,需要200毫秒,使用 TS 的字符串函数 includes 还不到100。能不能麻烦帮忙看一下代码问题,多谢
public testStr()

{

    let tmpStr = "Here is a simple example";

    let tmpStr2 = "tt";

    let srcArr = [];

    let findArr = [];

    for(let i = 0 ;i < tmpStr.length ; i++)

    {

        let tmpChar = tmpStr.codePointAt(i);

        srcArr.push(tmpChar);

        

    }

    for(let i =0 ; i< tmpStr2.length ; i++)

    {

        let tmpChar = tmpStr2.codePointAt(i);

        findArr.push(tmpChar);

    }

    let findStrLen = findArr.length-1;

    let lastChar = -1;

    let curChar = -1;

    let findIndex = findStrLen;

    let findResult = 0;

    for(let i = findStrLen ; i< srcArr.length;)//将字符串与搜索词头部对齐

    {

        curChar = srcArr[i];

        lastChar = findArr[findIndex];

        let tmpStr3 = "";

        for(let j = 0 ; j <= i;j++)

        {

            tmpStr3 += tmpStr[j];

        }

       // console.log("测试查找====",tmpStr3,curChar,lastChar);

        if(curChar != lastChar)//判断要搜索词尾部是否与原字符串相等

        {

            let state = -1;//不包含

            for(let j = 0 ; j< findArr.length ; j++)//判断原字符串是否包含在搜索词中

            {

                if(findArr[j] == curChar)

                {

                    state = findArr.length - (j+1);

                    break;

                }

            } 

            if(state == -1)

            {

                i+=findArr.length;

            }  

            else

            {

                 i+= state;

                 findIndex = findStrLen;

                

            }

        }

        else//好后缀 

        {

           

            if(findIndex > 0)

            {

                findIndex --;

                i--;

            }

            else

            {

               // console.log("完美查找===",i);

                findResult = 1;

                break;

            }

        }

    }

}

不好意思,我里面有很多测试代码没删除,脑子都迷糊了,今天重新测试了一下,100万单位查找 ts includes 函数 26毫秒比较稳定,自己写的BM查找算法 28毫秒浮动,他们两个运行效率差不多,误差不超过5毫米。我可能写的不够好,应该哪里多了不必要的代码

@TCMan


这是修改后的代码,10次测试结果,每次100万耗时,结果看来,BM确实效率很高,大佬你的思路太牛了
我估计应该还能再优化,我自己已经优化不出来了,我把代码贴出来,看看是否能帮忙优化一下。
public testStr(_srcStr,_findStr)

{

                  

    let lastChar = "";

    let curChar = "";

    let findIndex = _findStr.length-1;

   

    for(let i = _findStr.length-1 ; i< _srcStr.length;)//将字符串与搜索词头部对齐

    {

        curChar = _srcStr[i];

        lastChar = _findStr[findIndex];

        // let tmpStr3 = "";

        // for(let j = 0 ; j <= i;j++)

        // {

        //     tmpStr3 += srcArr[j];

        // }

        // console.log("测试查找====",tmpStr3,curChar,lastChar);

        if(curChar != lastChar)//判断要搜索词尾部是否与原字符串相等

        {

            let state = -1;//不包含

            for(let j = 0 ; j< _findStr.length ; j++)//判断原字符串是否包含在搜索词中

            {

                if(_findStr[j] == curChar)

                {

                    state = _findStr.length - (j+1);

                    break;

                }

            } 

            if(state == -1)

            {

                i+=_findStr.length;

            }  

            else

            {

                 i+= state;

                 findIndex = _findStr.length-1;

                

            }

        }

        else//好后缀 

        {

           

            if(findIndex > 0)

            {

                findIndex --;

                i--;

            }

            else

            {

               // console.log("完美查找===",i);

                return true;

                

            }

        }

    }

    return false;

}