UVa 401 Palindromes(常量数组+遍历)
原题地址
https://vjudge.net/problem/UVA-401
题意:判断输入的字符串是否满足回文、镜像。
回文即从左往右读和从右往左读的序列一样,镜像即可以通过翻转规则从一个字符变成另一个字符,如(3,E),(J-L)等。
解题思路
本题是《算法竞赛入门经典》的例题3-3,题目很简单,值得注意的是常量数组的妙用。
- 判断回文串很简单,只要遍历字符串,判断字符str[i]和字符str[len-1-i]是否相等,如果存在一个不相等的情况,则非回文串。
- 判断镜像串前,先把所有合法字符(字母和数字1-9,数字0不合法)的镜面字符存到常量字符串rev中,字母对应下标0-25,数字对应下标26-34,遍历时,判断字符str[i]和字符str[len-1-i]的镜面字符是否相等,如果存在一个不相等的情况,即非镜像串。
- 用pflag来记录输入串是否满足Palindrome,mflag来记录是否满足mirrored,一共有(00,01,10,11)这四种情况,由于四种情况各有输出的形式,所以根据2*p+m的值来选取输出形式msg。
AC代码
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#define MAXN 25
const char rev[] = "A 3 HIL JM O 2TUVWXY51SE Z 8 "; //数字0非法
const char* msg[] = //两种flag的组合情况对应的输出后缀
{
" -- is not a palindrome.\n", //pflag=0, mflag=0
" -- is a mirrored string.\n", //pflag=0,mflag=1
" -- is a regular palindrome.\n", //pflag=1,mflag=0
" -- is a mirrored palindrome.\n" //pflag=1,mflag=1
};
char reversed(char c)
{
if (isdigit(c))
return rev[c-'0'+25]; //数字(1-9)的索引从26开始
else
return rev[c-'A'];
}
int main(int argc, char const *argv[])
{
char str[MAXN];
while (~scanf("%s",str))
{
int pflag = 1, mflag = 1;
int len = strlen(str);
for (int i = 0; i<len; ++i)
{
if (str[i] != str[len-1-i]) //违反回文规则
pflag = 0;
if (str[i] != reversed(str[len-1-i])) //违反镜像规则
mflag = 0;
}
printf("%s", str); //源字符串
printf("%s\n", msg[2*pflag + mflag]); //输出后缀
}
return 0;
}