【紫书】例题3-3 回文词(Palindromes, UVa401)

【题目描述】

输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字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.

", s);
29         if ( P && !M ) printf ("%s is a regular palindrome.

", s);
30         if ( !P && M ) printf ("%s is a mirrored string.

", s);
31         if ( !P && !M ) printf ("%s is not a palindrome.

", 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. ", s, msg[m*2+p]); 个人觉得并没有十分的必要,这样费尽心思地去另建全局字符串数组,还要去考虑数组下标的实现细节,反不如四个逻辑判断来的清晰爽快。

原文地址:https://www.cnblogs.com/lilinilil/p/8450121.html