程宝P225 求一个字符串中连续出现次数最多的子串。

书上提供的方法,先将字符串的长度为1:n的后缀子串取出,针对每一个后缀子串,遍历其前缀子串,计算每个前缀子串连续出现次数,一旦发现有有连续子串出现,将计数器+1,然后针对该子串继续判断它是否会再次连续出现,若是则将计数+1,若不是,则跳出循环。继续计算下一个子串连续出现的次数。直到所有的后缀子串都遍历结束,输出最大值。

#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
#include <vector>
using namespace std;
//找出字符串中连续出现次数最多的子串
int main()
{
    string str,svbstr;
    getline(cin,str);
    int len=str.length();
    int i=0,j=0,cont=1,maxcont=1,k=0;
    vector<string> substrs;
    for(i=0;i<len;i++)
    {
        substrs.push_back(str.substr(i,len-i));
    }

    for(i=0;i<len;i++)
    {
        for (j=i+1;j<len;j++)
        {
            cont=1;//忘记清零
            if(substrs[i].substr(0,j-i)==substrs[j].substr(0,j-i))
        {
            cont++;
            for(k=2*j-i;k<len;k+=j-i)
            {
                if (substrs[k].substr(0,j-i)==substrs[j].substr(0,j-i))
                    ++cont;
                else
                    break;
            }
        }
        if (cont>maxcont)
        {
            maxcont=cont;
            svbstr=substrs[j].substr(0,j-i);
        }
        }
    }
    cout<<maxcont<<endl;
    cout<<svbstr;

}

方法二:

1、找出字符串中所有的子串,去除重复。

2、对于每一个子串,统计其连续出现的次数。

3、找出其中最大的次数和对应的子串。

#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
#include <vector>
#include <algorithm>
using namespace std;
void stable_unique(vector<string>& con);
//找出字符串中连续出现次数最多的子串
int main()
{
    string str,svbstr;
    string::size_type p,p1,np;
    vector<string> substrs;
    getline(cin,str);
    int i=0,j=0,len=str.length(),cont=1,maxcont=1,sub_len;

    for(i=1;i<=(len/2+1);i++)
        for(j=0;j<=len-i;j++)
            substrs.push_back(str.substr(j,i));
    for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
        cout<<*iter<<' ';
        cout<<endl;

        //去除重复的子串
        stable_unique(substrs);
        for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
        cout<<*iter<<' ';

    for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
    {
        sub_len=(*iter).length();
        p=str.find(*iter);
        while(p!=string::npos)
        {
            np=p+sub_len;
            p1=str.find(*iter,p+1);
            if (p1==np)
            {
                cont++;
            }
            else if(cont>maxcont)
            {
                maxcont=cont;
                svbstr=*iter;
                cont=1;
            }
            else
                cont=1;

            p=p1;
        }
    }
    cout<<endl;
    cout<<svbstr<<endl;
    cout<<maxcont;
}


void stable_unique(vector<string>& con)
{
    vector<string>::iterator it,ret,beg = con.begin();
    for (it = ++con.begin();it!=con.end();)
    {
        ret = find(beg,it,*it);//依次判定每个元素,在它之前查找是否有重复的元素,若有,则删除该判定元素。
        if (ret != it)
            it = con.erase(it);
        else
          ++it;
    }
}

题目的变化:找出连续出现的最长的子串

只需在第二种方法中修改一下,子串从长到短存入vector,再从长到短顺序判定,一旦发现有连续的子串,输出结果,结束程序。

#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
#include <vector>
#include <algorithm>
using namespace std;
void stable_unique(vector<string>& con);
//找出字符串中连续的最长的子串
int main()
{
    string str,svbstr;
    string::size_type p,p1,np;
    vector<string> substrs;
    getline(cin,str);
    int i=0,j=0,len=str.length(),sub_len
    ;

    for(i=len;i>=1;i--)
        for(j=0;j<=len-i;j++)
            substrs.push_back(str.substr(j,i));

    for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
        cout<<*iter<<' ';
        cout<<endl;

        //去除重复的子串
        stable_unique(substrs);
        for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
        cout<<*iter<<' ';

    for(vector<string>::iterator iter=substrs.begin();iter<substrs.end();iter++)
    {
        sub_len=(*iter).length();
        p=str.find(*iter);
        while(p!=string::npos)
        {
            np=p+sub_len;
            p1=str.find(*iter,p+1);
            if (p1==np)
            {
                cout<<endl<<*iter;
                return 1;
            }
            p=p1;
        }
    }
}


void stable_unique(vector<string>& con)
{
    vector<string>::iterator it,ret,beg = con.begin();
    for (it = ++con.begin();it!=con.end();)
    {
        ret = find(beg,it,*it);//依次判定每个元素,在它之前查找是否有重复的元素,若有,则删除该判定元素。保持顺序不变。
        if (ret != it)
            it = con.erase(it);
        else
          ++it;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值