0
点赞
收藏
分享

微信扫一扫

P2 统计单词数(KMP)

jjt二向箔 2022-04-21 阅读 59
算法c++
  • 题目链接:P2 统计单词数
  • 考查知识:KMP
  • 题意描述:在给定的文章中找出特定单词出现的次数和第一次出现的位置
  • 思路简析:KMP板子题吖 φ ( ∗  ̄ 0  ̄ ) φ(* ̄0 ̄) φ(0)
  • 具体代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6;
    int Next[N],cn,idx;//次数,下标 
    void getNext(string s,int Next[]){ 
    	Next[0]=-1;
    	int i=0,j=-1;//后缀指针i,前缀指针j
    	while(i<s.size()){
    		if(j==-1||s[i]==s[j]){//前缀指针从头开始匹配,或前后缀指针匹配成功 
    			i++;
    			j++;
    			if(s[i]==s[j])Next[i]=Next[j];//若匹配成功,则再次递归,记录后缀的前驱的前驱 
    			else Next[i]=j;//否则,记录前驱 
    		}else j=Next[j];//匹配失败令前缀指针回退 
    	} 
    } 
    int kmp(string t,string p) {
        getNext(p,Next);
        int i=0,j=0,ans=0;//文本串指针i,模式串指针j,匹配成功次数 
        while(i<t.size()){
            if(j==-1||t[i]==p[j]){//模式串从头开始匹配,或文本串指针模式串指针匹配成功 
                i++;
                j++;
                if(j==p.size()){//模式串完全匹配,匹配次数+1,模式串指针回退到前驱以待再次匹配 
    	            ans++;
    	            if(ans==1)idx=(i-1)-(p.size()-1);//记录第一次完全匹配的文本串下标,(i-1)是最后文本串匹配位置,(p.size()-1)是模式串首尾间距 
    	            j=Next[j];
    	        }
            }else j=Next[j];//文本串指针模式串指针匹配失败,模式串指针回退到前驱  
        }
        return ans;//返回出现次数
    }
    int main(){
    	string t,p;
    	getline(cin,p);
    	getline(cin,t);
    	for(int i=0;i<p.size();i++){//模式串全部转小写 
    		p[i]=tolower(p[i]);
    	}	 
    	for(int i=0;i<t.size();i++){//文本串全部转小写 
    		t[i]=tolower(t[i]);
    	}
    	p=" "+p+" ";
    	t=" "+t+" ";
    	cn=kmp(t,p); 
    	if(cn)cout<<cn<<' '<<idx<<endl; 
    	else cout<<-1<<endl;
    	return 0;
    }
    
举报

相关推荐

0 条评论