这道题看完题思路大致清晰,总体分开两个函数写,一个判断回文串,一个判断镜像串。
回文串判断好写,循环判断前半截与后半截是否一致即可。
关键在判断镜像串,一开始就也没多想,简单的判断呗~虽然知道要写好多,但也懒得细想。先判断字符串中有没有不是镜像字符的,有就直接返回0,没有再依次判断对称位置上的镜像字符是否对应,有不对应的就直接返回0,全都对应最后返回1.
虽然直接AC了,但这样写完了190行,突然感觉我好傻~
先贴出来吧~
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 10005 int pal(char str[MAX_SIZE])//palindrome { int i,j,slen; slen=strlen(str); for (i=0,j=slen-1;i<slen/2;i++,j--) if (str[i]!=str[j]) break; if (i==slen/2) return 1; return 0; } int mir (char str[MAX_SIZE])//mirrored { int i,j,slen; slen=strlen(str); for (i=0;i<slen;i++) { switch (str[i]) { case 'B': return 0; case 'C': return 0; case 'D': return 0; case 'F': return 0; case 'G': return 0; case 'K': return 0; case 'N': return 0; case 'P': return 0; case 'Q': return 0; case 'R': return 0; case '4': return 0; case '6': return 0; case '7': return 0; case '9': return 0; } } for (i=0;i<slen/2;i++) { switch(str[i]) { case 'A': if (str[slen-i-1]=='A') continue; else return 0; case 'E': if (str[slen-i-1]=='3') continue; else return 0; case 'H': if (str[slen-i-1]=='H') continue; else return 0; case 'I': if (str[slen-i-1]=='I') continue; else return 0; case 'J': if (str[slen-i-1]=='L') continue; else return 0; case 'L': if (str[slen-i-1]=='J') continue; else return 0; case 'M': if (str[slen-i-1]=='M') continue; else return 0; case 'O': if (str[slen-i-1]=='O') continue; else return 0; case 'S': if (str[slen-i-1]=='2') continue; else return 0; case 'T': if (str[slen-i-1]=='T') continue; else return 0; case 'U': if (str[slen-i-1]=='U') continue; else return 0; case 'V': if (str[slen-i-1]=='V') continue; else return 0; case 'W': if (str[slen-i-1]=='W') continue; else return 0; case 'X': if (str[slen-i-1]=='X') continue; else return 0; case 'Y': if (str[slen-i-1]=='Y') continue; else return 0; case 'Z': if (str[slen-i-1]=='5') continue; else return 0; case '1': if (str[slen-i-1]=='1') continue; else return 0; case '2': if (str[slen-i-1]=='S') continue; else return 0; case '3': if (str[slen-i-1]=='E') continue; else return 0; case '5': if (str[slen-i-1]=='Z') continue; else return 0; case '8': if (str[slen-i-1]=='8') continue; else return 0; } } return 1; } int main() { char str[MAX_SIZE]; while (gets(str)!=NULL) { int pa,mi; pa=pal(str); mi=mir(str); if (pa==0&&mi==0) printf("%s -- is not a palindrome.\n",str); else if (pa==1&&mi==0) printf("%s -- is a regular palindrome.\n",str); else if (pa==0&&mi==1) printf("%s -- is a mirrored string.\n",str); else if (pa&&mi) printf("%s -- is a mirrored palindrome.\n",str); printf("\n"); } return 0; }
AC之后感觉这题这么写实在太狠了,然后又看了一下网上代码,看到
首先可以用两个数组把题目中的表格存起来
char *ch = "AEHIJLMOSTUVWXYZ12358";
char *re = "A3HILJMO2TUVWXY51SEZ8";
这才受到启发,把原来代码进行了改进,但这样要注意判断镜像串的时候要讨论字符串长度是否为1,否则会WA
修改后AC的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 10005 int pal(char str[MAX_SIZE]) { int i,j,slen; slen=strlen(str); for (i=0,j=slen-1;i<slen/2;i++,j--) if (str[i]!=str[j]) break; if (i==slen/2) return 1; return 0; } int mir (char str[MAX_SIZE]) { char *ch="AEHIJLMOSTUVWXYZ12358"; char *re="A3HILJMO2TUVWXY51SEZ8"; int i,j,slen; slen=strlen(str); if (slen==1) { for (j=0;j<strlen(ch);j++) if (str[0]==ch[j]&&str[0]==re[j]) return 1; return 0; } else { for (i=0;i<slen/2;i++) { for (j=0;j<strlen(ch);j++) if (str[i]==ch[j]&&str[slen-i-1]==re[j]) { j=-1; break; } if (j!=-1) return 0; } return 1; } } int main() { char str[MAX_SIZE]; while (gets(str)!=NULL) { int pa,mi; pa=pal(str); mi=mir(str); if (pa==0&&mi==0) printf("%s -- is not a palindrome.\n",str); else if (pa==1&&mi==0) printf("%s -- is a regular palindrome.\n",str); else if (pa==0&&mi==1) printf("%s -- is a mirrored string.\n",str); else if (pa&&mi) printf("%s -- is a mirrored palindrome.\n",str); printf("\n"); } return 0; }