去年学数据结构时老师留的作业,写了一种字符串搜索算法。
在longstr中循环查找shortstr元素
举例如shortstr m位.Longstr,n位.
首先在longstr中匹配shortstr的第一个字符。匹配后,从longstr中匹配点后一位开始匹配shortstr的第二个字符,循环直至匹配到shortstr的最后一位字符,判断longstr中匹配点前m-1位是否与shortstr前m-1位相等,若是记录当前位置-m+1.若否重复先前工作.直至longstr的最后一位。
举例:
最坏的情况也只是longstr中每个字符比较两遍,所以时间复杂度为on
不过在写的过程中发现了当shortstr末尾存在多个相同字符时会出错。
针对这种情况,可以先搜索ac,再判断是否为acc。
最坏情况时间复杂度为o n * m1
m1为末尾重复字符的个数。
又仔细想了一下,对它进行了改进,先说一下优点和缺点。
优点
1是这个算法无论是理解起来,还是代码实现都非常简单。
2算法时间复杂度为o n
缺点
1不光是对acc类型的搜索字符会出现漏查,abcabc类型的也存在类似问题。
目前想到的解决办法是去掉重复的字串如查acc,就查ac,abcabc变为abc,先搜索不重复字串,再判断是否与重复字串匹配。
时间复杂度计算
对于普通的搜索字符串来说,只要将longstr中每个字符比较一次加上shortstr循环次数乘上shortstr的长度即可,shortstr循环次数小于n/m,
计算次数最多为 n + n/m * m = 2n
则时间复杂度为 o n
对于有重复的搜索字符串来说,如果采取去掉重复字串方法,其运行的次数是longstr中每个字符比较一次加上 修改后shortstr不重复字串 的循环次数乘上shortstr的长度即可,修改后shortstr不重复字串的循环次数为
n/(m-m1) ,,则修改后shortstr不重复字串的循环次数最多为n.例如搜索ssss字串,m - m1 = 1.
计算次数最多为 n + n * m = n + m * n
则时间复杂度为 o m*n
优化
但对于这种情况还有很大的改进空间,从而降低它的时间复杂度。
称修改后shortstr不重复字串为shortstr1
在shortstr1循环查找一次后先判断是否匹配,如果不匹配继续循环,如果匹配,再依次对shortstr去掉的重复部分进行匹配,如遇不匹配字符,就从当前位置重新进行shortstr1循环查找。反之则找到匹配字符串,返回当前位置。
时间复杂度计算
shortstr1每循环一次就要多比较一个字符(longstr与shortstr去掉的重复部分不匹配的第一个字符)其运行的次数是longstr中每个字符比较一次加上shortstr1的循环次数乘上1即可,
计算次数最多为 n + n * 1 = 2 * n
这样就可以保证其所有情况时间复杂度都为 o n
举例:
不过这些证明可能有错误,算法也有不完善的地方,希望大家可以一起完善。