1. 程式人生 > >【紫書】例題3-3 回文詞(Palindromes, UVa401)

【紫書】例題3-3 回文詞(Palindromes, UVa401)

jpg 多余 lin main 表示 pri 十分 span clas

【題目描述】

輸入一個字符串,判斷它是否為回文串以及鏡像串。輸入字符串保證不含數字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]); 個人覺得並沒有十分的必要,這樣費盡心思地去另建全局字符串數組,還要去考慮數組下標的實現細節,反不如四個邏輯判斷來的清晰爽快。

【紫書】例題3-3 回文詞(Palindromes, UVa401)