【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

求字符串中的回文最大长度

原创 2016年08月31日 15:49:13

目前,此问题最好的解法是Manacher算法,时间复杂度为O(n),本文还给出了另外两种便于理解的方法。

1.Manacher算法

//Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 
#include <iostream>
#include <algorithm>
using namespace std;

int Manacher(const string &data, const int &num)
{
	int len=num*2+1;//如:*1*2*3*
	string str(len,'*');
	for(int i=0;i<num;++i)
		str[2*i+1]=data[i];
	int *p=new int[len]();
	int mx = 0, id = 0;//mx表示0~(i-1)元素的最远右端;id表示具有最远右端中心元素点 
	for (int i = 1; i<len; ++i)
	{
	    p[i] = mx > i ? min(p[2*id-i], mx-i+1) : 1;
	    while (str[i + p[i]] == str[i - p[i]]) p[i]++;
	    if (i + p[i] > mx) 
		{
	        mx = i + p[i]-1;
	        id = i;
	    }
	}
	int res=*max_element(p,p+len);
	delete p;	
	return res-1;
}

int main()
{
	string str="12321476789987678998";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<Manacher(str,length)<<endl; 
}

2.暴力法(用到Manacher算法)思想

/*通过插入*来求最大回文长度,此时,最大回文长度为回文半径-1*/
#include <iostream>
#include <algorithm>
using namespace std;

int Manacher(const string &data, const int &num)
{
	int len=num*2+1;//如:*1*2*3*
	string str(len,'*');
	for(int i=0;i<num;i++)
		str[2*i+1]=data[i];
	int max_r=0;//记录最大半径 
	for (int i = 1; i<len-1; ++i)
	{ 
		int r=0; 
	    while ((i - r >= 0)&&(i + r <= len-1)&&(str[i + r] == str[i - r])) 
			r++;
	    if(r>max_r) max_r=r;
	} 	
	return max_r-1;//回文半径减一就是回文长度 
}

int main()
{
	string str="1232141267997621";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<Manacher(str,length)<<endl; 
}

3.用递归实现,复杂度渣到极限O(n*2^n)

/*用递归实现求最长回文长度,复杂度O(n*2^n)*/
#include <iostream>
using namespace std;
bool is_hw(char *start,char *end)
{
	while(start<end)
		if(*start!=*end) return false;
		else ++start,--end;
	return true;
} 
int urec_(char *start,char *end) 
{
	if(start==end) return 1;
	else if(start<end)
	{
		if(is_hw(start,end)) return end-start+1;
		else return max(rec_(start+1,end),rec_(start,end-1));
	} 
}

int main()
{
	string str="123214126798797621";
	int length=str.size();
	cout<<str<<" 的最长回文长度为:"<<rec_(&str[0],&str[0]+length)<<endl; 
}

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

求字符串中最大的回文长度

啊,接着上一篇判断字符串是否回文的问题,这一篇来解决另一个问题,求一个字符串当中最长的回文长度。 思路呢,因为考虑到一个任意的字符串,用中心向两边扩散的方法来判断回文是靠谱的。即,如果一段字符串是回...

程序员编程艺术第十二~十五章:IP访问次数,回文等问题(初稿)

程序员编程艺术第十二~十五章:中签概率,IP访问次数,回文等问题(初稿) 作者:上善若水.qinyu,BigPotato,luuillu,well,July。编程艺术室出品。 前言 本文的全部稿件是由我们编程艺术室的部分成员:上善若水.qinyu,BigPotato,luuillu,well,July共同完成,共分4个部分,即4道题: 第一部分、从一道题,漫谈数据结构、以及压缩、位图算法,由上善若水.qinyu完成, <

求对称字符串的最大长度算法

程序员面试100题之一:对称字符串的最大长度 分类: 数据结构 C/C++2011-08-14 16:55 5806人阅读 评论(0) 收藏 举报 面试nullgoogle算法 ...

经典算法题--求对策字符串的最大长度

题目:输入一个字符串,输出该字符串对称子字符串的最大长度,如输入google,则输出4. 方法一:思路很中规中矩,遍历这个字符串,若有发现相邻的两个字符相等,就循环判断与这两个字符相邻的两个字符是否相等,  直到不等,记下字符符合条件的字符个数。最大的个数即为所求。方法二:在方法一的基础上略有改动,思路还是一样,只不过不是一发现相邻的两个字符相等就开始循环, 而是根据上次出现对称的字符个数比较对应的两个字符是否相等,如果不等,那肯定是不用循环的,我们要求最大的长度吗?哈哈哈... 如果相等,就向里循环

找出字符串中对称的子字符串的最大长度(最长回文)[No. 14]

背景: 所谓对称子字符串,就是这个子字符串要么是以其中一个词对称:比如 “aba”, “abcba”;要么就完全对称:比如"abba", "abccba"。 问题: 给你一个字符串,找出该字符串中对称的子字符串的最大长度。 思路: 首先,我们用字符数组 char[] array 来保持这个字符串,假设现在已经遍历到第 i 个字符,要找出以该字符为“中心”的最长对称字符串,我们需要用另两个指针分别向前和向后移动,直到指针到达字符串两端或者两个指针所指的字符不相等。因为对称子字符串有两种情况,所以需要写出两种情况
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)