08-E. 可重叠子串 (Ver. I)

08-数据结构阶段复习一
题目描述
给定一个字符串(模式串)和一些待查找的字符串,求每个待查找字符串在模式串中出现的次数(可重叠)

输入
测试数据有多组(测试组数 <= 5),

第一行包括一个字符串P,长度不超过105,且非空串

第二行包括一个整数N,代表待查找的字符串数量 (1 <= N <= 5)

接下来的N行,每一行包括一个待查找的字符串,其长度不超过50,且非空串

输出
对于每组测试数据,

输出每个待查找字符串出现的次数,

具体输出见样例

输入样例
aabbcc
3
aa
bb
cc
ababab
1
aba

aa:1
bb:1
cc:1
aba:2

#include<iostream>
#include<string>
using namespace std;

class Cstring
{
    string str;
    int size;
public:
    Cstring():str(""),size(0){}
    void show()
    {
        cout<<str<<endl<<size<<endl;
    }
    void getnext(string t, int* next)
    {
        int j=0;next[0]=-1;
        int k=-1;
        int len=t.length();

        while (j<len)
        {
            if(k==-1||t[j]==t[k])
            {
                ++j; ++k;
                next[j]=k;
            }
            else
                k = next[k];
        }
    }
    int kmp(string t, int pos, int* next)
    {
        int i=pos,j=0;
        int len=t.length();
       
        while (i<size && j<len)
        {
            if (j==-1||str[i]==t[j])
            {
                ++i; ++j;
            }
            else
                j = next[j];
        }
       
        if (j == len)
            return i-j;
        
        return -1;
    }
    void setval(string sp)
    {
        str = "";
        str.assign(sp);
        
        size = sp.length();
    }
};

int main()
{
    string str;
    Cstring sp;
    int n;
    
    while (cin >> str)
    {
        sp.setval(str);
        cin>>n;
        string s;
        int len=str.length();
        int *next = NULL;
        
        while (n--)
        {
            cin>>s;
            int pos=0,sum=0;
            
            next=new int[s.length()];
            sp.getnext(s,next);
            while (pos<len)
            {
                pos = sp.kmp(s, pos, next);
                if (pos!=-1)
                {
                    sum++;
                    pos++;
                }
                else
                    break;
            }
            cout<<s<< ":"<<sum<<endl;
        }
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值