感谢建议,我再多研究一下
感谢您的建议,我感觉这个方法确实很好。
我现在的需求是,比如 “我没有带地图呀”,这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毫米。我可能写的不够好,应该哪里多了不必要的代码
这是修改后的代码,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;
}
