回文词( Palindromes, UVa401)
程序员文章站
2022-03-04 17:24:45
...
问题:
输入一个字符串, 判断它是否为回文串以及镜像串。 输入字符串保证不含数字0。 所谓回文串, 就是反转以后和原串相同, 如abba和madam。 所有镜像串, 就是左右镜像之后和原串相同, 如2S和3AIAE。 注意, 并不是每个字符在镜像之后都能得到一个合法字符。 在本题中, 每个字符的镜像如图3-3所示( 空白项表示该字符镜像后不能得到一个合法字符) 。
样例输入:
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)回文串:a的倒置==a;镜像串:a中不包含没有镜像的字符&&a倒置后按照字符镜像对应表替换==a
2)回文串:a[i]==a[n-1-i];镜像串:a[i]存在镜像字符且按照字符镜像对应表替换后==a[n-1-i]
个人代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string key;
while (cin >> key)
{
//a为原字符串倒置
string a = key;
reverse(a.begin(), a.end());
//b为原字符串倒置后替换镜像字符
string b = a;
bool flagMirror = true;
for (int i = 0; i < (int)b.size(); ++i)
{
switch(b[i])
{
case 'E': b[i] = '3'; break;
case 'J': b[i] = 'L'; break;
case 'L': b[i] = 'J'; break;
case 'S': b[i] = '2'; break;
case 'Z': b[i] = '5'; break;
case '2': b[i] = 'S'; break;
case '3': b[i] = 'E'; break;
case '5': b[i] = 'Z'; break;
case 'A':
case 'H':
case 'I':
case 'M':
case 'O':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case '1':
case '8':break;
default: flagMirror = false; break;
}
if (!flagMirror)
break;
}
if (flagMirror && key != b)
flagMirror = false;
if (key == a && flagMirror)
cout << key << " -- is a mirrored palindrome." << endl << endl;
else if (key == a)
cout << key << " -- is a regular palindrome." << endl << endl;
else if (flagMirror)
cout << key << " -- is a mirrored string." << endl << endl;
else
cout << key << " -- is not a palindrome." << endl << endl;
}
return 0;
}
#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]);
}
return 0;
}
总结:总体来说,还是代码不够简洁,字符镜像对应关系使用一个字符串存储即可。