[C++][题解]奇怪的计算题

48 篇文章 4 订阅

题目

题目描述

假期的你在家里收拾东西,偶然发现了一张幼儿园时的计算题。
题目只有加减,没有乘除。

这些题目简简单单。
可奇怪的是,某一些数字被莫名其妙的错写成了一些英文字母。
比如一道题

10+20-30

被错写成了

i0+20-E0

你还能计算出正确的答案吗?

给出一道形如" i 0 + 20 − E 0 i0+20-E0 i0+20E0"
的计算题(项数不一定只有3项,但一定小于1000项)。每一项都为一个整数。

每个数字可能变成的字母如下:

数字字母
0O或者o
1i或者l
2Z或者z
3E
4P
5R
6b
7L或T
8B
9q

输入格式

输入一行,是一个形如

i0+20-E0

的表达式。

输出格式

输出一个整数,表示计算结果。

题解

#include<iostream> 
#include<sstream>
#include<string>
using namespace std;
string Dir[10] = {"Oo","il","Zz","E","P","R","b","LT","B","q"};
int main(){
	string A;
	cin >> A;
	for(int i = 0;i < 10;i++){
		for(int j = 0;j < Dir[i].length();j++){
			char c = Dir[i][j];
			auto k = A.find(c);
			while(k != string::npos){
				A[k] = i + '0';
				k = A.find(c);
			}
		}
	}
	stringstream ss;
	ss << A;
	int res = 0,t;
	ss >> res;
	char c;
	while(ss >> c){
		ss >> t;
		if(c == '+')
			res += t;
		else
			res -= t;
	}
	cout << res << endl;
	return 0;
}
第五行
string Dir[10] = {"Oo","il","Zz","E","P","R","b","LT","B","q"};

这里要强调一种思维,
在遇到类似本题的——存在数据之间的映射关系,
要尝试使用类似于“查字典”的操作。
例如本代码中,将映射关系写在一个数组里,之后使用循环结构进行查找替换,对于本题编写起来会更加高效。

常见的一个错误是使用if一个一个进行特殊判断,如下:

for(int i = 0;i < A.length();i++){
	if(A[i] == 'O' || A[i] == 'o') A[i] = 0;
	if(A[i] == 'l' || A[i] == 'i') A{i] = 1;
	if(A[i] == 'Z' || A[i] == 'z') A[i] = 2;
	...
}

这种操作并非错误,但是这种方式不应该是我们首先考虑的操作。

如果题目中的映射关系更多或者可变,那么这种方法的效率将会更低,甚至不可实现。

九到十八行

这里用到了字符串的find函数,类似的操作在之前的一道题已经见过:[C++][题解]切蛋糕

十九行
stringstream ss;

这个是实例化了一个流对象,对象名叫ss
C++ 的常见有输入输出流、文件流、还有这个string流。
这个stringstream的使用方法有点类似于使用``cincout`。

对于

ss << A;

这句类似于cout << A,你可以想象是把A输出到一个看不见的屏幕,

ss >> t;

而这句类似与cin >> t,你可以想象是从那块看不见的屏幕重新将数据读入。
通过这一出一入的操作,便使用了stringstream实现了类型的转换。

可查看文章:C++ stringstream之妙用

24至30行

这里还要强调一个流操作的隐藏技巧。

对于

int numa,numb,numc;]
char c1,c2;
cin >> numa >> c1 >> numb >> c2 >> numc;

如果输入是

10+20−30
那么使用该语句可以正确得到想要的结果。

即在cin >> numa时,会在读入到第一个非数字的地方自动截断,即使字符和数字之间不存在空格。


原创不易,感谢支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wingaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值