题目:《算法竞赛入门经典》P48
https://blog.csdn.net/znx970902/article/details/80215928
输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字0。所谓 回文串,就是反转以后和原串相同,如abba和madam。所有镜像串,就是左右镜像之后和原
串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符。在本题 中,每个字符的镜像如图3-3所示(空白项表示该字符镜像后不能得到一个合法字符)。
图3-3 镜像字符
输入的每行包含一个字符串(保证只有上述字符。不含空白字符),判断它是否为回文 串和镜像串(共4种组合)。每组数据之后输出一个空行。
样例输入:
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA
样例输出:
NOTAPALINDROME -- is not a palindrome.
ISAPALINILAPASI -- is a regular palindrome.
2A3MEAS -- is a mirrored string.ATOYOTA -- is a mirrored palindrome.
分析:1、回文数的判断,是将数字前后颠倒,然后判断与原来的数字是否相同。
但是这在回文词的判断上不是很好使用。
2、书上是直接将前后部分分别拎出来进行比较,判断是否是回文词。
3、数字作为字符串输入进去,也可以用这种方法判断,挺好的。
4、镜像词的判断,在回文词的基础上做一个映射就好。
书上的代码:
#include<stdio.h> #include<string.h> #include<ctype.h> const char*rev="A 3 HIL JM O 2TUVWXY51SE Z 8 ";//镜像串字符常量 const char*msg[]={"not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome"};//字符常量 char r(char ch) { if(isalpha(ch)) return rev[ch-'A']; return rev[ch-'0'+25]; }//用来之后判断是否为镜像串 int main() { char s[30]; while(scanf("%s",s)==1) { int len=strlen(s); int p=1,m=1; for(int i=0;i<(len+1)/2;i++) { if(s[i]!=s[len-1-i]) p=0;//不是回文串 if(r(s[i])!=s[len-1-i]) m=0;//不是镜像串 } printf("%s -- is %s.\n\n",s,msg[m*2+p]);//amazing!!!!! } return 0; }
我没咋瞅懂那个r函数是什么意思。遂,通过指针,建立两个数组之间的映射。
我的代码:
#include<stdio.h>
#include<string.h>
const char *pre="AEHIJLMOSTUVWXYZ12358" ;
const char *rev="A3HILJMO2TUVWXY51SEZ8";
const char *msg[]={" is not a palindrome."," is a regular palindrome.","is a mirrored string.","is a mirrored palindrome."};
char r(char ch)//输入保证只有pre中的字符
{
return rev[strchr(pre,ch)-pre];
}
int main()
{
char s[100];
scanf("%s",s);
int i,j;
int m=1,n=1;
for(i=0,j=strlen(s)-1;i!=j;i++,j--)//判断是不是回文数
if(s[i]!=s[j])
m=0;
for(i=0,j=strlen(s)-1;i!=j;i++,j--)//判断是不是镜像数
if(r(s[i])!=s[j])
n=0;
printf("%s----%s\n",s,msg[m]);
printf("%s----%s\n",s,msg[2+n]);
return 0;
}//上面两个for循环可以合并。
结果:
相关文章: