UVa OJ 401

题目描述:原题很长,大意是判断一个字符串是否回文串或镜像串。所谓回文串就是正读倒读都一样,所谓镜像串就是镜面反射后与原来一样。

每一个有镜面反射关系的字符,题目都给出了对应字符,比如“E”和“3”,“A“和”A“。题目特别强调了0和O被认为是相同的,所以在字符中只会出现O(valid character)。

关键的知识点:题目每一行都给出了一个包含”valid character“的字符串,所以用gets这种处理一行的函数比较好,但是gets不如fgets,后者不存在缓冲区溢出漏洞。

注意题目声明了输出的每一行必须被一行空行分隔,故每行输出必须有两个\n。

解题思路:将每个字符A_Z,1_9都在数组a里给予一个编号,如‘A’是1,‘1’是27,如果有镜面关系,如A和自己有镜面关系,则a【1】=1,E和3有镜面关系,则a【5】=29,a【29】=5,这样看两个数是否有镜面关系只要比较编号是否相等即可。没有镜面关系的统一设成0。

将字符转化为编号用到num函数,注意字母和数字的算法是不同的。

设置两个”flag”,m和p,分别代表是否镜像和是否回文。初值为1,每个字符判断一次,只要一次不满足,立刻变为0.

关于字符的个数,可以分奇数和偶数讨论,那样代码比较冗长。本人采用的是单独处理中间元素的方法。

最后注意判断m、p是否为零,不能用if(!m&&!p),因为&&是一假即假,只会判断(!m)成立就跳出了。所以还是要用if else分类讨论。

程序如下:

#include <stdio.h>
#include <string.h>
#include<ctype.h>
int num(char p);
char s[1000000]="";
int main(void)
{
    int i;
    int a[36]={0};
     a[1]=1;a[8]=8;a[9]=9;a[13]=13;a[15]=15;a[20] =20;a[21]=21;a[22]=22;a[23]=23;a[24]=24;a[25]=25;a[27]=27;a[34]=34;
     a[5]=29;a[10]=12;a[12]=10;a[19]=28;a[26]=31;a[28]=19;a[29]=5;a[31]=26;
    while(fgets(s,1000000,stdin)!=NULL)
    {
          int m=1,p=1,len;
          len=strlen(s)-1;s[len]='\0';
                for(i=0;i<len/2;i++)
                     {
                         if(s[i]!=s[len-i-1])
                                 {
                                     p=0;
                                     if(a[num(s[i])]!=num(s[len-i-1])){ m=0;break;}
                                 }
                         else if(a[num(s[i])]!=num(s[len-i-1])) {m=0;break;}

                     }
                if((len%2==1)&&!a[num(s[len/2])]) m=0;

                    if(!m)
                       {
                           if(!p) printf("%s -- is not a palindrome.\n\n",s);
                           else printf("%s -- is a regular palindrome.\n\n",s);
                       }
                       else
                       {
                           if(!p)printf("%s -- is a mirrored string.\n\n",s);
                           else printf("%s -- is a mirrored palindrome.\n\n",s);
                       }
        }
        return 0;
}
int num(char p)
{
    if(isalpha(p)) return p-'A'+1;
    if(isdigit(p)) return p-'0'+26;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值