最长回文串

原串:    w aa bwsw f d
新串:   # w# a # a # b# w # s # w # f # d #
在此之前要对字符串进行统一,即任意字符串在其所有字母之间插入特殊字符,这样可以将其总数变成奇数。(所有字符之间都插入特殊字符,则必有一个字符在中间是对称点,两边插入是防止越界和占位。)
void pk(int n,char str[])
{
int i;//记录数组的指针
int mx = 0;//最大长度
int id;//最大长度的半径值的位置。
int p[n];//用来存储每个字符的半径。
for(i=1; i<n; i++)//匹配这个字符串.此句也表明这个算法的时间复杂度为(n);最前面有占位符所以起始为一。
{
    if( mx > i )
    {
             p[i] = MIN( p[2*id-i], mx-i );//下面有解释。
    }
    else
    {
         p[i] = 1;//任意一个字符,其半径最小为一。
    }
    for(; str[i+p[i]] == str[i-p[i]]; p[i]++);//判断是否相同,是则匹配下一个。可形成一个简易算法。
    if( p[i] + i > mx )//当前匹配长度是否大于过去的最大长度。
    {
        mx = p[i] + i;//如大于,则替换。
        id = i;
    }
}

}
代码转自->Manacher;(并非原创);
用这个模拟 p[i] = MIN( p[2*id-i], mx-i );// mx = p[i] + i;所以mx的值是可以大于i的,当且仅当p[i]已被匹配过,此过程参考。
例如:

str[4]//p[0]是特殊符,用来占位,故p[4]是第二个a。
p[4]=4;//则匹配p[5]时p[5]应直接等于3,因为与其对应的p[3]=3,其关于p[4]对称。所以匹配p[5]时是从p[8]开始的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值