CH3例题:最长回文子串

自己写的,不知道对不对,可能会太慢了:(枚举子串起点、从大到小的长度)

#include<stdio.h>
#include<string.h>
#include<ctype.h>
const int MAXN = 5000 + 100;

int main()
{
	char org[MAXN], chr[MAXN];
	int pos[MAXN];
	//Confuciuss say: Madam, I'm Adam
	while(fgets(org, MAXN, stdin) )
	{
		int chr_len = 0;
		for(int i = 0; i < strlen(org); ++i)
		{
			if(isalpha(org[i]))
			{
				chr[chr_len] = tolower(org[i]);
				pos[chr_len] = i;
				++chr_len;
			}
		}
		bool done = false;
		for(int sub_len = chr_len; sub_len >= 1 && !done; --sub_len)
		{
			for(int i = 0; i+sub_len <= chr_len && !done; ++i)
			{
				//is [i, i+sub_len) a palindrome string?
				bool ok = true;
				for(int j = i; j <= i+sub_len/2; ++j)
				{
					if(chr[j] != chr[2*i+sub_len-1-j])
					{
						ok = false;
						break;
					}
				}
				if(ok)
				{
					int start = pos[i];
					int end = pos[i+sub_len-1];
					for(int k = start; k <= end; ++k)
					{
						putchar(org[k]);
					}
					putchar('\n');
					done = true;
				}
			}
		}
	}
	return 0;
}

参考了书的思路,枚举子串终点,长度:

写的比书繁琐

#include<stdio.h>
#include<string.h>
#include<ctype.h>
const int MAXN = 5000 + 100;

int main()
{
	char org[MAXN], chr[MAXN];
	int pos[MAXN];
	//Confuciuss say: Madam, I'm Adam
	while(fgets(org, MAXN, stdin) )
	{
		int chr_len = 0;
		for(int i = 0; i < strlen(org); ++i)
		{
			if(isalpha(org[i]))
			{
				chr[chr_len] = tolower(org[i]);
				pos[chr_len] = i;
				++chr_len;
			}
		}
		//start from 0 to output the leftmost one of the same length
		int max = 0, orgstr, orgend;
		for(int middle = 0; middle < chr_len; ++middle)
		{
			for(int sub_len = 0; middle-sub_len >=0 && middle + sub_len < chr_len; ++sub_len)
			{
				//is [middle-sub_len, middle+sub_len] palindrome string?
				bool ok = true;
				for(int j = 0; j <= sub_len; ++j)
				{
					if(chr[middle-j] != chr[middle+j])
					{
						ok = false;  //书上写的更简洁
                        //书上:只要遇到一对不满足的chr,表明已经找到了以这个middle为中心的最长回文子串;不需要内层这个循环
						break;
					}
				}
				if(ok && 2*sub_len+1 > max)
				{
					max = 2*sub_len + 1;
					orgstr = pos[middle - sub_len];
					orgend = pos[middle + sub_len];
				}
			}

			for(int sub_len = 0; middle-sub_len >=0 && middle + 1 + sub_len < chr_len; ++sub_len)
			{
				//is [middle-sub_len, middle+1+sub_len] palindrome string?
				bool ok = true;
				for(int j = 0; j <= sub_len; ++j)
				{
					if(chr[middle-j] != chr[middle+1+j])
					{
						ok = false;
						break;
					}
				}
				if(ok && 2*sub_len+2 > max)
				{
					max = 2*sub_len + 2;
					orgstr = pos[middle - sub_len];
					orgend = pos[middle + 1 + sub_len];
				}
			}
		}
		for(int k = orgstr; k <= orgend; ++k)
		{
			putchar(org[k]);
		}
		putchar('\n');
	}
	return 0;
}

按书上的写:

#include<stdio.h>
#include<string.h>
#include<ctype.h>

int main()
{
	const int MAXN = 5000 + 100;
	char org[MAXN], chr[MAXN];
	int pos[MAXN];
	while( fgets(org, MAXN, stdin))
	{
		int maxlen = 0;
		for(int i = 0; i < strlen(org); ++i)
		{
			if(isalpha(org[i]))
			{
				chr[maxlen] = tolower(org[i]);
				pos[maxlen++] = i;
			}
		}

		int x, y, max = 0;
		for(int middle = 0; middle < maxlen; ++middle)
		{
			for(int len = 0; middle-len>=0 && middle+len<maxlen; ++len)
			{
				if(chr[middle-len] != chr[middle+len]) break;
				if(2*len + 1 > max) 
				{
					max = 2*len + 1;
					x = pos[middle-len];
					y = pos[middle+len];
				}
			}
			for(int len = 0; middle-len>=0 && middle+1+len<maxlen; ++len)
			{
				if(chr[middle-len] != chr[middle+1+len]) break;
				if(2*len + 2 > max) 
				{
					max = 2*len + 2;
					x = pos[middle-len];
					y = pos[middle+1+len];
				}
			}
		}
		for(int i = x; i <= y; ++i)
		{
			putchar(org[i]);
		}
		putchar('\n');
	}
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值