字符串匹配(蛮力)

博客皆个人学习过程中整理,如有问题,欢迎大家指正。
本文链接: https://blog.csdn.net/qq_42017331/article/details/102162308

串匹配

对基于同一字符表的任何文本串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)。
参考文献:《数据结构》邓俊辉

猜你喜欢

转载自blog.csdn.net/qq_42017331/article/details/102162308