编程之法第一章【回文判断+字符串转化成整数】

本文介绍如何将字符串转换为整数并处理溢出问题,同时提供了一个基础的回文判断方法及Manacher算法的高效实现。

字符串转化成整数


字符串转化成整数是个比较容易的问题,比较刺手的问题就是可能会溢出、所以第一章中对溢出处理的技巧比较妙。

int型值的最大值为max_int=2147483647。如果直接转化的时候n*10+c可能就会大于max_int。所以我们可以通过除法了防止溢出。如果n>max_int/10.那么n*10肯定大于max_int了,但是n这时候还没有大于max_int。所以可以通过n>max_int来提前结束判断防止溢出。如果n==max_int的时候就要判断n>max_int%10.当然这是对于正数来说的,int型的最小值等于-(max_int)-1;


#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

int strToInt(const char*str){
	
	static const int MAX_INT=(int)((unsigned)~0>>1);
	static const int MIN_INT=-(int)((unsigned)~0>>1)-1;
	unsigned int n=0;
	
	//处理是否为空 
	if(str==0) return 0;
	//空格 
	while(isspace(*str)) ++str;
	//处理正负
	int sign=1;
	if(*str=='+'||*str=='-'){
		if(*str=='-') sign=-1;
		str++;
	} 
	while(isdigit(*str))
	{
		int c=*str-'0';
		if(sign>0&&(n>MAX_INT/10||(n==MAX_INT/10&&c>MAX_INT%10))){
			n=MAX_INT;
			break;
		}
		else if(sign<0&&(n>(unsigned)MIN_INT/10||(n==(unsigned)MIN_INT/10&&n>
		(unsigned)MIN_INT%10))){
			n=MIN_INT;
			break; 
		}
		n=n*10+c;
		str++;
	}
	return sign>0?n:-n;
}
int main(){
	
	char s[20]={'1','2','3','4','5','9','9','9','9','9','9','9','9','9','9'};
	cout<<strToInt(s)<<endl;
	
}


回文判断


这也是个很简单很基础的问题了,但是如果字符串很长的话就要用到mancher了,这个方法在暑假的时候看过,但是已经忘得差不多了,现在重新看的话还是有那么一点印象。所以处理起来没有那么刺手。就是细节需要注意。

先说基础的做法吧。就是暴力判断,但是要主要分两种情况,回文长度为奇数和偶数的时候。

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

int longestPalindrome(const char*s,int n) {
	int i,j,max,c;
	if(s==0||n<1) {
		return 0;
	}
	max=0;
	for(i=0; i<n; i++) {
		for(j=0; i>=j&&i+j<n; j++) {
			if(s[i-j]!=s[i+j]) {
				break;
			}
			c=2*j+1;
		}
		max=max>c?max:c;

		for(j=0; i>=j&&(i+j+1<n); j++) {
			if(s[i-j]!=s[i+j+1]) break;
			c=2*j+2;
		}
		max=max>c?max:c;
	}
	return max;
}

int main(){
	
	char s[10]={'a','s','d','d','s','v'};
	cout<<longestPalindrome(s,6)<<endl;
}


Manacher方法,详细的不说了,有一点需要注意的地方,就是为了更好地处理越界的问题,把第一个字符设为‘$’,当然前提是你的字符串里面没有这个字符。为什么呢?因为s[i-p[i]]这里会越界。

图书馆要闭馆了,就这样了。。。

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;
int p[50];
int Manacher(const char *s,int n){
	
	int i,j,max=1,mx=0,id;
	for(i=1;i<n;i++){
		if(mx>i){
			p[i]=min(p[2*id-i],mx-i);
		}
		else{
			p[i]=1;
		}
		while(s[i+p[i]]==s[i-p[i]]) p[i]++;
		if(p[i]+i>mx){
			mx=p[i]+i;
			id=i;
		}
	}
	for(int i=0;i<n;i++){
		max=max>p[i]?max:p[i]; 
	}
	return max;
}

int main(){
	char s[50]={'1','2','2','1','2','3','2','1'};
	char ss[50];
	int k=0;
	ss[k]='$';
	for(int i=0;i<8;i++){
		ss[k++]='#';
		ss[k++]=s[i];
	} 
	ss[k++]='#';
	cout<<Manacher(ss,k)-1<<endl;
}




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值