串的模式匹配算法(求子串位置的定位函数Index(S,T,pos))


串的模式匹配的一般方法如算法4.5(在bo4-1.cpp 中)所示:由主串S 的第pos 个字
符起,检验是否存在子串T。首先令i 等于
pos(i 为S 中当前待比较字符的位序),j 等于
1(j 为T 中当前待比较字符的位序),如果S 的
第i 个字符与T 的第j 个字符相同,则i、j 各
加1 继续比较,直至T 的最后一个字符(找
到)。如果还没到T 的最后一个字符,比较就
出现了不同(没找到),则令i 等于pos+1,j 等
于1,由pos 的下一个位置起,继续查找是否
存在子串T。这个过程如图410 所示。

在算法4.5 中,主串S 的指针i 总要回溯,特别是在如图410 所示的有较多字符匹
配而又不完全匹配的情况下,回溯得更多。这时,主串S 的一个字符要进行多次比较,显
然效率较低。
如果能使主串S 的指针i 不回溯,在有些情况下效率则会大为提高。这是可以做到
的,因为主串S 中位于i-1,i-2,⋯ 的字符恰和子串T 中位于j-1,j-2,⋯ 的字符相
等,如图410 所示。仍以图410 为例,当S 和T 在第i(终值)个字符处字符不相符
时,i 仍保持在终值处不动,j 回溯到第1 个字符与i 的当前字符继续进行比较。j 回溯到第
几个字符是由子串T 的模式决定的。算法4.7 根据子串T 生成的next 数组指示j 回溯到第
几个字符。next 数组的意义是这样的:如果next[j]=k

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用字符匹配算法子串在主中的位置。其中最经典的算法是KMP算法。 KMP算法的核心思想是利用已经匹配过的信息,避免在匹配过程中出现重复的比较。具体来说,首先预处理出模式的最长公共前后缀长度LPS数组,然后在匹配过程中,当匹配失败时,利用LPS数组中记录的已匹配前缀信息,将模式向右移动尽可能少的距离,使得模式中该位置之前的字符都能匹配成功,从而避免了不必要的比较。 下面是KMP算法的C++代码实现: ```cpp #include <iostream> #include <string> #include <vector> using namespace std; vector<int> computeLPS(const string& pattern) { int n = pattern.size(); vector<int> lps(n, 0); int i = 1, j = 0; while (i < n) { if (pattern[i] == pattern[j]) { lps[i++] = ++j; } else if (j > 0) { j = lps[j - 1]; } else { i++; } } return lps; } int kmp(const string& text, const string& pattern) { int m = text.size(), n = pattern.size(); vector<int> lps = computeLPS(pattern); int i = 0, j = 0; while (i < m) { if (text[i] == pattern[j]) { i++, j++; if (j == n) { return i - j; } } else if (j > 0) { j = lps[j - 1]; } else { i++; } } return -1; } int main() { string text = "ABABDABACDABABCABAB", pattern = "ABABCABAB"; int pos = kmp(text, pattern); if (pos != -1) { cout << "Pattern found at position " << pos << endl; } else { cout << "Pattern not found" << endl; } return 0; } ``` 在上面的代码中,computeLPS函数用于预处理模式的LPS数组,kmp函数用于实现KMP算法,并返回子串在主中的位置。需要注意的是,如果子串不在主中出现,则kmp函数返回-1。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值