字符串匹配(蛮力)

串匹配

对基于同一字符表的任何文本串T(|T| = n)和模式串P(|P| = m);
判定T中是否存在某一子串与P相同
若存在,则返回子串P在T中的起始位置。

版本A:
int match_A(string T, string P){
 	int i = 0, j = 0;
 	int n = T.length(), m = P.length();
 	while(i < n && j < m){
  		if(T[i] == P[j]){
   			i++; j++; 
  		} else {
   			i -= j - 1;
   			j = 0;
  		}
 	}
 	return i - j;//结果 > T.length()则未找到 
}

很好理解,T中字符同P轮流比较,若相等则T和P同时后移。若不等,则T后移,P呆在初始位置。上述代码不好理解的地方可能在==i -= j - 1;==这一句。其实很好理解,若T与P首次不相等,此时P在初始位置0处,减1操作相当于i+1。对于P不是呆在初始位置,同样好理解,因为初始都在0位置,因此相当于在原基础上+1。

版本B:
int match_B(string T, string P){
 	int n = T.length(), m = P.length();
 	int i = 0, j;
 	for(i = 0; i < n-m+1; i++){
  		for(j = 0; j < m; j++)
   			if(T[i+j] != P[j])
    				break;
  		if(j >= m) break;
 	}
 	return i;//i > p.lenght()则未找到 
}

同样是轮流比较,不同的是T只需要比较前n-m+1个即可,因为若存在匹配情况,则只会出现在前n-m+1个中,在这之后P的长度已小于T的剩余长度,所以又怎么能匹配成功呢?

完整代码:
#include<iostream>
using namespace std;

int match_A(string T, string P){
 	int i = 0, j = 0;
 	int n = T.length(), m = P.length();
 	while(i < n && j < m){
  		if(T[i] == P[j]){
   			i++; j++; 
  		} else {
   			i -= j - 1;
   			j = 0;
  		}
 	}
 	return i - j;//结果 > T.length()则未找到 
}
int match_B(string T, string P){
 	int n = T.length(), m = P.length();
	int i = 0, j;
 	for(i = 0; i < n-m+1; i++){
  		for(j = 0; j < m; j++)
   			if(T[i+j] != P[j])
    				break;
  		if(j >= m) break;
 	}
 	return i;//i > p.lenght()则未找到 
}

int main(){
 	string T, P;
 	cin >> T >> P;
 	cout << match_A(T, P) << endl;
 	cout << match_B(T, P) << endl;
 	return 0;
}
时间复杂度分析:

蛮力算法至多迭代(n-m+1)* m次。因此当n >> m时,时间复杂度为O(n*m);最好情况下也要O(n+m)。
参考文献:《数据结构》邓俊辉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值