【题目描述】
输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字0.所谓回文串,就是反转以后和原串相同,如abba和madam。所有镜像串,就是左右镜像之后和原串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符。在本题中,每个字符的镜像如图所示(空白项表示该字符镜像后不能得到一个合法字符)。
输入的每行包含一个字符串(保证只有上述字符。不含空白字符),判断它是否为回文串和镜像串(共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 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <ctype.h> 5 6 #define MAX (int)1e4 7 8 using namespace std; 9 10 const char RS[] = "A 3 HIL JM O 2TUVWXY51SE Z 8 "; // 常量字符数组,存对应镜像字符 11 12 char rev( char c ) 13 { 14 if ( isalpha(c) ) return RS[c - ‘A‘]; // 注意下标的处理 15 else return RS[c - ‘0‘ + 25]; 16 } 17 18 int main() 19 { 20 char s[MAX]; 21 while ( scanf ("%s", s) == 1 ) { 22 int len = strlen(s); 23 int P = 1, M = 1; 24 for ( int i = 0; i < (len+1) / 2; i++) { // 判断到一半即可停止,+1为了包含最中间字符的自身比较,用于镜像判断 25 if ( s[i] != s[len - 1 - i] ) P = 0; 26 if ( rev(s[i]) != s[len - 1 -i] ) M = 0; 27 } 28 if ( P && M ) printf ("%s is a mirrored palindrome.\n\n", s); 29 if ( P && !M ) printf ("%s is a regular palindrome.\n\n", s); 30 if ( !P && M ) printf ("%s is a mirrored string.\n\n", s); 31 if ( !P && !M ) printf ("%s is not a palindrome.\n\n", s); 32 } 33 34 return 0; 35 }
【总结】
只能说作者太强了。。看作者的代码非常过瘾,思路清晰,也没有多余的地方。现在的能力远远达不到这种水平,可以说是有了榜样吧。
但关于书中代码
const char* msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"};
以及对应的 printf ("%s -- is %s.\n\n", s, msg[m*2+p]); 个人觉得并没有十分的必要,这样费尽心思地去另建全局字符串数组,还要去考虑数组下标的实现细节,反不如四个逻辑判断来的清晰爽快。