UVA401回文串+镜像串判断

题目链接:https://www.luogu.com.cn/problem/UVA401

回文串的判断不难,难点在于镜像串的判断,所谓镜像串就是根据题目的镜像表两次镜像后保持原样就是镜像串,第一次镜像后得到的是这个串的倒像,所以判断一个镜像串的依据就是一次翻转后是这个串的倒像。

问题在于怎么镜像,写个函数整个串镜像?还是写个函数只镜像单个字符?显然如果我们镜像整个串会麻烦很多,所以选择镜像单个字符。随之而来的问题是我们怎么存题目给的镜像表,我一开始的想法是用两个string分别存原字符和镜像字符,然后每次镜像时先找到该字符位置,然后找这个位置对应的镜像字符。后来看到题解就惊了,怎么就这么点代码。

看完才明白自己想复杂了,这个镜像表是有规律的,从A ~ Z 26个字母 + 1 ~ 9 ( 9个数字),但凡是有规律的东西都能够做简化,我之前想要用两个string,但存原字符的那个string可以省略,然后我们也不需要查找字符再找镜像,因为镜像表是有规律的。具体做法看代码理解。

#include <bits/stdc++.h>
using namespace std;

string s = "A   3  HIL JM O   2TUVWXY51SE Z  8 ";
string res[] = { "is not a palindrome.","is a regular palindrome.","is a mirrored string.","is a mirrored palindrome." };

int mir(char a) {
	if (isalpha(a))return s[a - 'A'];//字母
	return s[a - '0' + 25];//数字
}

int main()
{
#ifdef LOCAL
	freopen("1.txt", "r", stdin);
#endif // LOCAL
	string a;
	int t1, t2;//分别用来判断是否为回文串和镜像串
	while (cin >> a) {
		t1 = t2 = 1;
		int len = a.length();
		for (int i = 0; i < len; i++) {
			if (a[i] != a[len - i - 1])t1 = 0;
			//如果a[i]的镜像字符不等于a[len-i-1],t2=0
			if (mir(a[i]) != a[len - i - 1])t2 = 0;
		}
		cout << a << " -- " << res[t1 + 2 * t2] << endl;
		cout << endl;
	}
	return 0;
}

这是根据书上的例子稍作修改的代码,我觉得很巧妙的一个地方在最后输出的结果上,如果是一般人,都会在最后写上4个if判断,不同情况输出,而书的作者直接先把四个结果存起来,我们知道两位二进制可以得到4种不同的结果0,1,2,3,正好我们的输出结果也就是四种,所以就将t1,t2作为二进制位得到一个数t1+2t2(这里也可以t2+2t1,但res数组存的字符串顺序也要随之改变),用这个数作为下标来访问存放结果的数组,输出字符串。
这个方法保证了每组t1,t2都有一个唯一对应的结果t1+2*t2,而且不同的t1,t2一定有不同的输出结果。
只用少量的代码就能解决一个看似复杂的问题,这就是大犇吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值