字符串的最大平方串

来源:互联网 发布:hdc电视直播软件 编辑:程序博客网 时间:2024/05/17 02:29

字符串的平方串

苏大  希望失望

养天地正气,法古今完人


定义:一个字符串和其自身的连接所得的字符串称为该字符串的平方串。例如字符串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 stringint const MAXSIZE = 50;//CachSizeconst 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;    }