字符串的平方串
苏大 希望失望
养天地正气,法古今完人
定义:一个字符串和其自身的连接所得的字符串称为该字符串的平方串。例如字符串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;
}