趣题系列
(1)回文词是一种对称的字符串,也就是说,一个回文词,从左到右读和从右到左读得到的结果是一样的,任意给定一个字符串,通过插入若干字符都可以变成一个回文词,请设计一个算法求出给定字符串变成回文词所需插入的最少字符数。(如Ab3bd在插入两个字符后可以变成dAb3bAd或Adb3bdA,但插入两个以下的字符无法使它变成一个回文词。)
别看答案,想一个更好的算法
#include<stdio.h>
#include<string.h>
int min; /* min为最小插入字符数 */
int ishw(char string[5001]) /* 判断字符串string是否为回文词 */
{
int i;
for(i=0;i<strlen(string) && i<strlen(string)-1-i;i++)
if(string[i]!=string[strlen(string)-1-i])
return 0;
return 1;
}
void getmin(int len,char input[5001]) /* 得到最小插入字符数 */
{
char nextstring[5001];
int i,j,ishwen=0;
if(len<min)
{
if(ishw(input))
min=len;
else
{
for(i=0;i<strlen(input) && i<strlen(input)-i-1;i++)
{
if(input[i]!=input[strlen(input)-i-1])
break;
else
{
input[i]=input[strlen(input)-i-1]='`';
ishwen=1;
}
}
if(!ishwen)
{
for(i=0;i<strlen(input);i++)
nextstring[i]=input[i+1];
getmin(len+1,nextstring);
strcpy(nextstring,input);
nextstring[strlen(nextstring)-1]='\0';
getmin(len+1,nextstring);
}
else
{
for(j=0,i=0;i<strlen(input);i++)
if(input[i]!='`')
nextstring[j++]=input[i];
nextstring[j]='\0';
getmin(len,nextstring);
}
}
}
}
void main(void)
{
char input[5001],slen[5]; /* input为待处理的字符串 */
int i;
FILE *fp;
min=10000;
fp=fopen("palin.in","r");
if(fp==NULL)
{
printf("can't open file palin.in\n",min);
return;
}
fscanf(fp,"%s",slen);
fscanf(fp,"%s",input);
printf("%s %s\n",slen,input);
fclose(fp);
getmin(0,input);
printf("%d\n",min);
fp=fopen("palin.out","w");
if(fp==NULL)return;
fprintf(fp,"%d\n",min);
fclose(fp);
}