题目
题目描述
假期的你在家里收拾东西,偶然发现了一张幼儿园时的计算题。
题目只有加减,没有乘除。
这些题目简简单单。
可奇怪的是,某一些数字被莫名其妙的错写成了一些英文字母。
比如一道题
10+20-30
被错写成了
i0+20-E0
你还能计算出正确的答案吗?
给出一道形如"
i
0
+
20
−
E
0
i0+20-E0
i0+20−E0"
的计算题(项数不一定只有3项,但一定小于1000项)。每一项都为一个整数。
每个数字可能变成的字母如下:
数字 | 字母 |
---|---|
0 | O或者o |
1 | i或者l |
2 | Z或者z |
3 | E |
4 | P |
5 | R |
6 | b |
7 | L或T |
8 | B |
9 | q |
输入格式
输入一行,是一个形如
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
的使用方法有点类似于使用``cin、
cout`。
对于
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
时,会在读入到第一个非数字的地方自动截断,即使字符和数字之间不存在空格。
原创不易,感谢支持。