算法题目二:寻找最长重复子序列(4) 求给定字符串重复最长的子串

本文为转载。原文地址:http://hi.baidu.com/taozpwater/item/7b705317ca8479f4746a8470

谢谢作者的智慧与分享!

1、问题

       输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它。

 

2、解析

       例如“yyabcdabjcabceg”,输出应该为abc和3。

       可以将字符串yyabcdabjcabceg分解成如下子串

       yyabcdabjcabceg

       yabcdabjcabceg

       abcdabjcabceg

       .......

       eg

       g

       1)从最大子串开始正序查找,然后逆序查找,如果两次查找位置不一致说明存在重复子串。

       2)利用后缀数组求解

 

3、方法一

<cpp>

 

#include <iostream>

#include<string>

using namespace std;

int main()

{

    string str,tep;

    cout<<"请输入字符串"<<endl;

    cin>>str;

    for(int i=str.length()-1;i>1;i--)

    {

        for(int j=0;j<str.length();j++)

        {

            if(j+i<=str.length())

            {

                size_t t=0;

                size_t num=0;

                tep=str.substr(j,i);//从大到小取子串

                t=str.find(tep);//正序查找,从0开始查找字符串tep,返回tep的位置

                num=str.rfind(tep);//逆序查找,从0开始从后向前查找字符串,返回tep的位置

                                    //从前后分别查找字符串,正常情况下是刚开始的长串找不到的,到后来的短串前后才会重

                if(t!=num)//如果两次查找位置不一致说明存在重复子串

                {

                    cout<<tep<<" "<< t+1<<endl;//输出子串及位置

                    return 0;//因为是从长到短,所以再短的也就不找了

                }

            }

        }

    }

    return 0;

}

</cpp>

4、方法二

 

 #include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

 

#define MAXCHAR 5000 //最长处理5000个字符

 

char c[MAXCHAR], *a[MAXCHAR];

 

int comlen(char *p, char *q)

{

    int i = 0;

    while(*p && (*p++ == *q++))

        ++i;

    return i;

}

/**

  * 比较字符串

  */

int pstrcmp(const void *p1, const void *p2)

{

    return strcmp(*(char* const *)p1, *(char* const*)p2);

}

 

int main()

{

    char ch;

    int n = 0;

    int i, temp;

    int maxlen = 0, maxi = 0;

    printf("Please input your string:\n");

    while((ch = getchar()) != '\n')

    {

        a[n] = &c[n];

        c[n++] = ch;

    }

    c[n] = '\0';

    qsort(a, n, sizeof(char*), pstrcmp);

    for(i = 0; i < n - 1 ;++i)

    {

        temp = comlen(a[i], a[i+1]);

        if(temp > maxlen)

        {

            maxlen = temp;

            maxi = i;

        }

    }

    

    printf("%.*s\n",maxlen, a[maxi]);

    return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值