chenglong7997

串的模式匹配【转自Orisun】


串的模式匹配就是从一个主串中找到子串出现的位置,如主串是"asd234",子串是"d2",那么算法返回的结果就应该是2.

一种最朴素的想法就是BF算法,我就不讲了," 最朴素"嘛,就是你脑子里现在想的那种算法.

比较优一点的是KMP算法.

更优的是BM算法.

BM的改进算法是Sunday Algorithm.

现在我给出BF和Sunday两种算法的代码,然后再和STL中string在find函数进行比较.

STL中string在find函数示例:

string name("AnnaBelle");

string::size_type  pos=name.find("Anna");    //pos==0

#include<iostream>
#include<cstring>
#include<ctime>
using namespace std;
 
int BF(const string &str1,const string &str2){
    int len1=str1.size();
    int len2=str2.size();
    int i=0;
    int j=0;
    while(i<len1 && j<len2){
        if(str1[i]==str2[j]){
            i++;
            j++;
        }
        else{
            i+=1-j;
            j=0;
        }
    }
    if(j==len2)
        return i-j;
    else
        return -1;
}
int findChar(const string &str,char c){
    int len=str.size();
    for(int i=len-1;i>=0;i--){
        if(str[i]==c){
            return i;
        }
    }
    return -1;
}
int Sunday(const string &str1,const string &str2){
    int len1=str1.size();
    int len2=str2.size();
    int i=0;
    int j=0;
    int begin=i;
    while(i<len1 && j<len2){
        if(str1[i]==str2[j]){
            i++;
            j++;
        }
        else{
            int index=findChar(str2,str1[begin+len2]);
            if(index<0){
                begin+=len2+1;
                j=0;
                i=begin;
            }
            else{
                int ps=len2-index;
                begin+=ps;
                j=0;
                i=begin;
            }
        }
    }
    if(j==len2)
        return i-j;
    else
        return -1;
}
int main(){
    const int N=1000000;
 
    string str1,str2;
    cout<<"Input MainString: ";
    getline(cin,str1);
    cout<<"Input SubString: ";
    getline(cin,str2);
     
    clock_t start,finish;
     
    start=clock();
    for(int i=0;i<N;i++)
        BF(str1,str2);
    finish=clock();
    cout<<"BF:"<<BF(str1,str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl;
     
    start=clock();
    for(int i=0;i<N;i++)
        Sunday(str1,str2);
    finish=clock();
    cout<<"Sunday:"<<Sunday(str1,str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl;
     
    start=clock();
    for(int i=0;i<N;i++)
        str1.find(str2);
    finish=clock();
    cout<<"STL:"<<str1.find(str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl;
    return 0;
}

下面是两个测试用例:

STL总是出奇地快,Sunday并不是总比最笨的BF算法快.

原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun

posted on 2012-03-28 02:26 Snape 阅读(118) 评论(0)  编辑 收藏 引用 所属分类: 算法


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

my

搜索

最新评论

阅读排行榜

评论排行榜