算法设计--串匹配问题:BF算法、KMP算法、BM算法

来源:互联网 发布:学美容知乎 编辑:程序博客网 时间:2024/04/30 11:14
#include<iostream>#include<string>using namespace std;/** BF算法* 基本思想:*从主串S的第一个字符开始和模式T(子串)的第一个字符进行比较,若相等,则继续比较两者的后续字符;*若不相等,则从主串S的第二个字符开始和模式T的第一个字符进行比较,重复上述过程,若T中的字符全部比较完毕,则说明本趟匹配成功;*若最后一轮匹配的起始位置是n-m(n为主串的长度,m为模式T的长度),则主串S中剩下的字符不足够匹配整个模式T,匹配失败。*这个算法称为朴素的模式匹配算法,简称BF算法。*/int BF(string &s, string &t){int i=0,j=0,count=0;//i指向主串s,j指向子串t,count计算匹配的字符长度while(i < s.size()){if(s.at(i) == t.at(j))//如果匹配{i++;//指针后移j++;count++;}else {//匹配失败i++;j = 0;count = 0;}if(count == t.size()){cout<<"字符串匹配成功,起始位置为:"<<i - count + 1<<endl;return (i - count + 1);}}cout<<"字符串匹配失败!"<<endl;return 0;}//KMP算法中求next数组void GetNext(string &t, int *next){next[1] = 0;int j = 1; int k = 0;while(j < t.size()){if((k == 0) || (t[j] == t[k])){j++;k++;next[j] = k;}else k = next[k];}}//KMP算法实现/**伪代码:* 1.在串S和串T中分别设比较的起始下标i和j* 2.循环直到S中所剩字符长度小于T的长度或T中所有字符均比较完毕*2.1 如果S[i] = T[j],则继续比较S和T的下一个字符,否则*   2.2 将j向右滑动到next[j]位置,即j=next[j];*   2.3 如果j = 0,则将i和j分别加1,准备下一趟比较*  3.如果T中的所有字符均比较完毕,则返回匹配的起始下标,否则返回0*/int KMP(string &s, string &t){int i = 0,j = 0;int n = t.size();//子串的长度int *next = new int[n];GetNext(t, next);//求出每一个j对应的next[j]while(i < s.size() && j < t.size()){if(j == 0 || (s.at(i) == t.at(j))){i++;j++;}else {j = next[j];}if(j == t.size()){int index = i - t.size() + 1;cout<<"字符串匹配成功,起始位置为:"<<index<<endl;return index;}}cout<<"字符串匹配失败!"<<endl;return 0;}//BM算法中的dist函数(滑动距离函数)int dist(string &t, char ch)//t为子串,ch为主串中的任意字符{int len = t.size();int i = len - 1;if(ch == t.at(i))return len;i--;while(i >= 0){if(ch == t.at(i)){return len - 1 - i;//返回滑动距离}else {i--;}}return len;}//BM算法/*基本思想:有*假设将主串中自位置i起往左的一个子串与模式进行从右到左的匹配过程中,若发现不匹配*,则下次应从主串的i+dist(Si)位置开始重新进行新一轮的匹配,其效果相当于把模式和主串均向右* 滑过一段距离dist(Si),即跳过dist(Si)个字符而无需进行比较。*/int BM(string &s, string &t, int n, int m){//主串的长度为n,模式串的长度为m,主串和模式的数组下标从0开始int i = m - 1;while(i <= n){int j = m - 1;while(j > 0 && s.at(i) == t.at(j)){j--;i--;}if(j == 0) {cout<<"字符串匹配成功,起始位置:"<<i + 1<<endl;return i+1;}else i = i + dist(t,s.at(i));}return 0;}int main(){string s,t;cout<<"请输入主串S:"<<endl;cin>>s;cout<<"请输入子串T:"<<endl;cin>>t;//调用BF算法进行字符串匹配cout<<"BF算法:"<<endl;cout<<BF(s,t)<<endl;//调用KMP算法进行字符串匹配cout<<"KMP算法:"<<endl;cout<<KMP(s,t)<<endl;//调用BM算法进行字符串匹配cout<<"BM算法:"<<endl;cout<<BM(s,t,s.size(),t.size())<<endl;system("pause");return 0;}


原创粉丝点击