蓝桥杯————随笔练(字符串回文)

一.中心扩展法(模板)

#include <bits/stdc++.h>
#include <string>
//求回文 -- 中心扩展法
using namespace std;


//选定字符串s,左边界left,右边界right
int expand_stringCenter(string s,int left,int right){
	while (left >= 0 && right <s.length() && s[left] == s[right])
	{
		left--;
		right++;
	}
	return right-left-1;//(right-1)-(left+1)+1;
}

//中心扩展法的核心
string Palindrom(string s)
{
	if(s.empty()) return "";   //如果传入空字符串
	int start =  0,end = 0;    //回文的起始索引和结束索引
	for(int i = 0;i < s.length();i++){
		int len_1 = expand_stringCenter(s,i,i);    //如果这回文是有中心的。即奇数
		int len_2 = expand_stringCenter(s,i,i+1);    //如果这回文是偶数的,那就是找不到回文中心
		int len = max(len_1,len_2);        //判断回文是奇数还是偶数的
		
		if(len > end-start+1)//相同长度更新后者,覆盖结果
		{
			start = i-(len-1)/2;
			end = i +len/2;
		}
		//如果是if(len > end-start),那就返回第一个最长回文串的子串
	}
	
	return s.substr(start,end-start+1);
}


int main() {
	string s;
	s = "ababd";
	cout << "最长回文子串:" << Palindrom(s) ;
	return 0;
}

补充:关于substr的用法

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "Hello, World!";
    cout << str.substr(7) << endl;             // 输出: World!
    cout << str.substr(7, 5) << endl;           // 输出: World
    return 0;
}

二.manacher算法(模板)

#include <bits/stdc++.h>
#include <vector>
#include <string>

//manacher算法,要点在于预处理和回文寻找

using namespace std;

//预处理字符串
string Get_nowstring(string s){
	string t = "#";
	for(int i = 0;s[i];++i)
	{
		(t+=s[i])+="#";
	}
	return t;
}
/*
    a    b    a    c
    #    a    #    b    #     a    #    c
*/


string Palindrom(string s){
	string T = Get_nowstring(s);
	
	int n = T.size();
	vector<int> P(n,0);//存储每个位置的回文半径
	
	int C = 0,R = 0;//center radius(已知的字符串的右边界)
	
	for(int i = 0;i<n;i++)
	{
		int Symmetry = 2*C -i;    //i关于C的对称点
		if(i<R) P[i]=min(R-i,P[Symmetry]);
		
		int left = i-(P[i]+1);
		int right = i+(P[i]+1);
		while(left>=0 && right < T.size() && T[left] == T[right])
		{
			left--;
			right++;
			P[i]++;
			
		}
		if(i+P[i]>R)    //已知字符串右边界更新
		{
			C = i;
			R = i+P[i];
		}
		
		
	}
	
	int maxlen=0,center = 0;
		for(int i = 0;i<n;i++)
		{
			if(P[i]>=maxlen) maxlen=P[i],center=i;
			
		}
		
	//处理预处理字符
	int start = (center - maxlen)/2;
	return s.substr(start,maxlen);
}

int main() {
	string s = "ababd";
	cout << "最长回文子串:" << Palindrom(s) ;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值