马拉车算法的C++实现

  1. 马拉车算法是专门查找字符串中最长回文子串的一种算法,该算法好像目前只有这么一个功能。他相比于单纯的暴力匹配搜索算法的算法效率提高了很大。单纯的暴力搜索是O(n),但是马拉车算法的算法效率是O(n)。该算法充分利用了回文字符串的特性,来进行回文字符串的查找。大大的提高了查找字符串的效率。

#include
#include
using namespace std;
string dealStr(string str1)//字符串处理函数,在字符串中插入特殊字符,不论字符串的字符数量是奇数还是偶数,使字符串字符个数都变成奇数。计算时不用讨论字符数目的奇偶性。字符串直接处理即可。
{
string str2 = “#”;
for (int i = 0; i < str1.size(); i++)
{
str2 = str2 + str1[i];
str2 = str2 + “#”;
}
return str2;
}
string flndLastPalindromeString(string str)
{
string str2 = dealStr(str);
int len = str2.size();
int *halfLenStr = new int[len];
for (int i = 0; i < len; i++)
{
halfLenStr[i] = 0;//在这里我们记录一个以i为中心的回文字符串半径。
}
int rightcenter = 0;//表示最远右边界的以该核心构成回文。
int rightside = 0;//定义我们当前回文字符串最远右边界。
int longest = 0;//表示最长回文半径。
int center = 0;//表示最长回文半径核心
for (int i = 0; i < len; i++)
{
bool needCalc = true;
if (i < rightside)//当字符位置小于回文最远右边界的时候。需要分情况讨论
{
int leftcenter = 2 * rightcenter - i;//计算和i对应的左边回文核心的位置
halfLenStr[i] = halfLenStr[leftcenter];//先把左边回文核心的回文半径赋值给i的回文半径。
if (halfLenStr[i] + i < rightside)//当该回文半径右边界小于最大右边界的时候,不用对i进行再计算。
{
needCalc = false;
}
if (halfLenStr[i] + i > rightside)//当该回文半径右边界大于最大右边界的时候,需要对i为回文半径的重新计算。
{
halfLenStr[i] = rightside - i;//更新i的回文半径
}
}
if (needCalc)
{
while (i - 1 - halfLenStr[i] >= 0 && i + 1 + halfLenStr[i] < len)
{
if (str2[i - 1 - halfLenStr[i]] == str2[i + 1 + halfLenStr[i]])
{
halfLenStr[i]++;//进行新的回文半径的更新。
}
else
{
break;
}
}
rightside = i + halfLenStr[i];//更新最大回文的核心和回文半径
rightcenter = i;
if (halfLenStr[i] > longest)
{
longest = halfLenStr[i];
center = i;
}
}
}
string str3 = “”;
for (int i = center - longest + 1; i <= center + longest; i += 2)//计算出最大回文半径。
{
str3 = str3 + str2[i];
}
return str3;
}
int main()
{
cout << flndLastPalindromeString(“abcdefgfedhijoop”) << endl;
cout << flndLastPalindromeString(“aaaaa”) << endl;
cout << flndLastPalindromeString(“abcdefgfedcba”) << endl;
system(“pause”);
return 0;
}
比如
cabadabae
001210101
上述是数字是各个字符的回文半径。当计算第二个cabad的回文半径的时候,我们发现最长边界已到cabada,而核心为a,就是说a的左边有一个和d一样字符才能和d回文。先这样理解一下吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值