字符串的回文与镜像
给你一个字符串,如何判断这个字符串是不是回文串和镜像串。
看试一道很简单的题,但真正能把握住这道题却很难!
下面介绍三种方法,各有亮点:
第一种方法:先把可以镜像的字符用Hash表给存储起来,给出的字符串的一半入栈,如果这个字符串的长度为奇数,则这个字符串中间这个字符如果镜像后的字符和原来不相同,则这个字符串肯定不是镜像字符串,然后每次出栈一个,和下一个字符进行对比,如果出栈的字符和下一个字符不相等,则肯定不是回文字符串,如果在Hash表中,并镜像后,和下一个相等,则有可能是镜像字符串 ;
详细代码如下:
#include <cstdio> #include <cstring> #include <stack> #include <map> using namespace std; int main() { char s[21]; map<char, char> rev; rev['A'] = 'A'; rev['H'] = 'H'; rev['I'] = 'I'; rev['E'] = '3'; rev['J'] = 'L'; rev['L'] = 'J'; rev['M'] = 'M'; rev['O'] = 'O'; rev['T'] = 'T'; rev['U'] = 'U'; rev['V'] = 'V'; rev['W'] = 'W'; rev['X'] = 'X'; rev['S'] = '2'; rev['Y'] = 'Y'; rev['Z'] = '5'; rev['1'] = '1'; rev['2'] = 'S'; rev['3'] = 'E'; rev['5'] = 'Z'; rev['8'] = '8'; while (scanf("%s", s) != EOF) { stack<char> checker; int len = strlen(s); bool palin = true, mirror = true; int pos = 0; for (; pos < len / 2; pos++) { checker.push(s[pos]); } if (len % 2 != 0) { if (!rev.count(s[pos])) mirror = false; if (rev[s[pos]] != s[pos]) mirror = false; pos++; } for (; pos < len; pos++) { if (checker.top() != s[pos]) { palin = false; } if (!rev.count(checker.top()) || rev[checker.top()] != s[pos]) { mirror = false; } checker.pop(); } printf("%s -- ", s); if (palin && mirror) printf("is a mirrored palindrome."); else if (palin && !mirror) printf("is a regular palindrome."); else if (!palin && mirror) printf("is a mirrored string."); else if (!palin && !mirror) printf("is not a palindrome."); printf("\n\n"); } return 0; }
第二种方法:
先用Hash表将可以镜像的字符存储起来,从给出的字符串的最后一位开始逆序重建字符串,如果重建的和原来相同,就是回文,如果经过镜像之后重建的和原来相同,就是镜像串!
详细代码如下:
#include<iostream> #include<algorithm> #include<sstream> #include<fstream> #include<utility> #include<cstdlib> #include<cstring> #include<string> #include<bitset> #include<vector> #include<cstdio> #include<cctype> #include<cmath> #include<queue> #include<deque> #include<stack> #include<map> #define ll long long #define sc scanf #define pf printf #define pi 2*acos(0.0) using namespace std; int main() { string s,a,b; char m[3000]; memset(m,NULL,sizeof(m)); m['A']='A'; m['E']='3'; m['H']='H'; m['I']='I'; m['J']='L'; m['L']='J'; m['M']='M'; m['O']='O'; m['S']='2'; m['T']='T'; m['U']='U'; m['V']='V'; m['W']='W'; m['X']='X'; m['Y']='Y'; m['Z']='5'; m['1']='1'; m['2']='S'; m['3']='E'; m['5']='Z'; m['8']='8'; while(cin>>s){ a=b=""; int len=s.size(); for(int i=len-1;i>=0;i--) { a+=s[i]; b+=m[s[i]]; } if (s==a && s==b) cout<<s<<" -- is a mirrored palindrome."<<endl<<endl; else if (s==a && s!=b) cout<<s<<" -- is a regular palindrome."<<endl<<endl; else if (s!=a && s==b) cout<<s<<" -- is a mirrored string."<<endl<<endl; else cout<<s<<" -- is not a palindrome."<<endl<<endl; } return 0; }
第三种方法:
#include<iostream> #include<string.h> #include<string> #include<stdio.h> using namespace std ; int Is_H_W( char *s ) { int len = strlen(s) - 1 ; for(int i = 0 ; i < len ; i++,len--) if(s[i] != s[len]) return 0 ; return 1 ; } char a[] = {'A',' ',' ',' ','3',' ',' ','H','I','L',' ','J','M',' ','O',' ',' ',' ','2','T','U','V','W','X','Y','5'} ; char b[] = {'1','S','E',' ','Z',' ',' ','8',' '} ; int Is_J_X( char *s ) { bool flag = false ; int len = strlen(s) - 1 ; if((len+1)%2) flag = true ; for(int i = 0 ; i <= len ; i++ , len--) { if(s[i] >= 'A' && s[i] <= 'Z') { if(a[s[i] - 'A'] != s[len]) return 0 ; } else { if(b[s[i] - '1'] != s[len]) return 0 ; } } return 1 ; } int main() { char s[22] ; while(gets(s)) { if(Is_H_W(s)&&Is_J_X(s)) printf("%s -- is a mirrored palindrome.\n\n",s) ; else if(!Is_H_W(s)&&Is_J_X(s)) printf("%s -- is a mirrored string.\n\n",s) ; else if(Is_H_W(s)&&!Is_J_X(s)) printf("%s -- is a regular palindrome.\n\n",s) ; else printf("%s -- is not a palindrome.\n\n",s) ; } return 0 ; }