字符串的最大平方串

字符串的平方串

苏大  希望失望

养天地正气,法古今完人


定义:一个字符串和其自身的连接所得的字符串称为该字符串的平方串。例如字符串abc的平方串为”abc”+”abc”=”abcabc”,”abcabc”称为”abc”的平方串。

子串:字符串的子串,按顺序选择若干字符构成的串。形式化定义如下:

1.      子串中任一字符都必须在原串中存在;

2.      子串中的字符顺序与这些字符出现在原串中的顺序是一致的。

问题:现在给定一个长度为len的字符串,求其长度最大的平方串。

实例

                          a : 1                          frfr: 4                                     frrf: 2 

                         aa: 2                     ccguitccguit:12                      guigiu:4

                        aaa: 2                abcabccguitccguit: 12             abcabc:6

 问题分析

        现给定”abcabc”求其最大平方串,直观分析,可知其平方串有:a, b, abab, acac, bcbc, abcabc。我们采用的方式为枚举所有的平方串,并从中找出长度最大的。如何生成这些平方串呢?我们来看下abab,事实上(a,a)插入(b,b)就能生成(a,b,a,b)。(a,b,a,b)插入(c,c)就能生成(a,b,c,a,b,c)。由此可知:新的平方串是在某个平方串中插入元素(x,x)来形成的。

         设现有平方串(x1,x2,x3,x4),那么,x1=x3,x2=x4。现有新的元素(x5,x6)(index(x6)>index(x4)),只有当x5=x6时才可能插入到(x1,x2,x3,x4)。且  x6只能插入到x4之后,那么由于x2=x4且解必须仍是平方串,那么,x5的索引只能介于x2,x3索引之间。在这些保证下,形成的解才是“平方解”。反之,其他情况不能构成平方串。

       在下面给出了自己的一个笨拙的求解方式。代码中注释掉了解的保存即long long solution以及对应值的更改,若有需要记录,可以将注释删掉。

求解代码

#include <iostream>
using namespace std;

//the max length of string
int const MAXSIZE = 50;
//CachSize
const long long  CachSize = 50;

struct {
    int len;
    struct{
        //store the location of second - first head of subsolution
        //we shuold make sure the range value of x should bigger than MAXSIZE
        unsigned char x;

        //store the location of first-seconf tail of subsolution
        //we shuold make sure the range value of y should bigger than MAXSIZE
        unsigned char y;

        //the length of subsolution
        unsigned char clen;
        //use 64bits(>50) to store the solution of this substring
        //if you don't want to store solution, you can delete this
        //long long solution;
    } TV[CachSize];
} PV[MAXSIZE];

void main(){

    char str[MAXSIZE];
    cin >> str;
    int len = strlen(str);

    //Initialization
    for (int i = 0; i < len; i++)
        PV[i].len = 0;
    int maxl = 1;

    //Handle Process
    for (int i = 0; i < len; i++)//trave the string str
        for (int j = i - 1; j >= 0; j--)//go back to search the str[j]==str[i]
            if (str[j] == str[i] && i != j + 1){
                //construct the subsolution(str[j],str[i])
                PV[j].TV[PV[j].len].x = i;
                PV[j].TV[PV[j].len].y = j;
                PV[j].TV[PV[j].len].clen = 2;
                if (PV[j].TV[PV[j].len].clen>maxl)
                    maxl = PV[j].TV[PV[j].len].clen;
                //storwe the path of solution
                //PV[j].TV[PV[j].len].solution = 0;
                //PV[j].TV[PV[j].len].solution |= (long long(1)<<j);
                //PV[j].TV[PV[j].len].solution |= (long long(1) << i);
                PV[j].len++;

                //if str[j] and str[i] can insert to the subsolution which is begin with str[k]
                for (int k = j - 1; k >= 0; k--)
                    for (int l = 0; l < PV[k].len; l++)
                        if (PV[k].TV[l].y < j && j < PV[k].TV[l].x){//can insert to construct a new subsolution. So, we should insert this new solution to the storage of PV[k]
                            //update some value
                            PV[k].TV[PV[k].len].x = PV[k].TV[l].x;
                            PV[k].TV[PV[k].len].y = j;
                            PV[k].TV[PV[k].len].clen = PV[k].TV[l].clen + 2;

                            if (PV[k].len >= CachSize)
                            {
                                cout << "leak over: you should expand the value of CachSize\n";
                                return;
                            }
                            if (PV[k].TV[PV[k].len].clen>maxl)
                                maxl = PV[k].TV[PV[k].len].clen;
                            PV[k].len++;
                        }    
            }
    cout << maxl;
    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值