【表达式计算】:
给定一个字符串形式的表达式,保证每个字符串表达式中仅包含加(+)这1种运算符,计算并输出表达式结果。
要注意的是,+号两边的数据仅可能包含数字字符、小数点字符与特殊字符,特殊字符包括!@#,这些特殊字符的加法运算有特别的规则:
!+!=0
!+@=13
!+#=4
@+@=7
@+#=20
#+#=5
注意:
1.保证每个表达式仅包含—个运算符
2.保证表达式一定可运算且有数据结果
3.保证运算符两边数据有效(不会出现包含两个小数点之类的无效数据)
4.表达式内不存在空格
5特殊字符的加法运算符合交换律
6.如果表达式中包含特殊字符,则运算中不会出现数字与特殊字符的加法运算
7.表达式两边的数据均不以0开头,比如不会出现这样的表达式:0250+0110
【解答要求】:
时间限制:C/C++1000ms,其他语言:2000ms
内存限制:C/C++ 256MB,其他语言:512MB
【输入】:
第一行:代表字符串长度(长度在[1,100]之间)
第二行:代表一个字符串表达式
【输出】:
输出一行,输出表达式结果
注意:
注意:小数最后位如果为0则省略,如结果250.010则输出250.01,结果250.0则省略为250;同时,如果计算结果为”0250”,也需以最简化形式“250"输出。
【样例】1
输入:15
123.45#1+126.53@
输出:250.0001
解释:#+@=20,即进2位,表达式结果为250.0001
竖式运算如下:
123.45#1
126.53@
-------------
250.0001
#include <iostream> #include <string> using namespace std; int special_add(char s1, char s2) { if (s1 == '!') { if (s2 == '!') return 0; else if (s2 == '@') return 13; else if (s2 == '#') return 4; } else if (s1 == '@') { if (s2 == '@') return 7; else if (s2 == '#') return 20; else if (s2 == '!') return 13; } else if (s1 == '#') { if (s2 == '#') return 5; else if (s2 == '@') return 20; else if (s2 == '!') return 4; } return 0; } int main() { int len; string exp; cin >> len >> exp; int pos = exp.find("+"); // 查找加号位置 string op1 = exp.substr(0, pos); // 第一个操作数 string op2 = exp.substr(pos + 1); // 第二个操作数 string op11, op12, op21, op22; int pos1 = op1.find("."); if (pos1 != -1) { op11 = op1.substr(0, pos1); op12 = op1.substr(pos1 + 1); } else { op11 = op1; op12 = "0"; } int pos2 = op2.find("."); if (pos2 != -1) { op21 = op2.substr(0, pos2); op22 = op2.substr(pos2 + 1); } else { op21 = op2; op22 = "0"; } if (op11.size() < op21.size()) swap(op11, op21); if (op12.size() < op22.size()) swap(op12, op22); int addition_carry = 0; for (int i = op12.size() - 1; i > -1; i--) { if (i > op22.size() - 1) { if (op12[i] == '!' || op12[i] == '@' || op12[i] == '#') { op12[i] = '0'; } } else { if (op12[i] == '!' || op12[i] == '@' || op12[i] == '#') { int special_res = special_add(op12[i], op22[i]) + addition_carry; op12[i] = special_res % 10 + '0'; addition_carry = special_res / 10; } else { int n1 = int(op12[i]) - int('0'); int n2 = int(op22[i]) - int('0'); op12[i] = (n1 + n2 + addition_carry) % 10 + '0'; addition_carry = (n1 + n2 + addition_carry) / 10; } } } string s(op11.size() - op21.size(), '0'); op21 = s + op21; for (int i = op11.size() - 1; i > -1; i--) { if (op11[i] == '!' || op11[i] == '@' || op11[i] == '#') { int special_res = special_add(op11[i], op21[i]) + addition_carry; op11[i] = special_res % 10 + '0'; addition_carry = special_res / 10; } else { int n1 = int(op11[i]) - int('0'); int n2 = int(op21[i]) - int('0'); op11[i] = (n1 + n2 + addition_carry) % 10 + '0'; addition_carry = (n1 + n2 + addition_carry) / 10; } } if (addition_carry > 0) { char first_num = addition_carry + '0'; op11.insert(0, 1, first_num); } //去掉首0 int i = 0; for (i; i < op11.size(); i++) if (op11[i] != '0') break; if (i >= 0 && i < op11.size()) op11 = op11.substr(i); if (i >= op11.size()) op11 = "0"; //去掉尾0 i = op12.size() - 1; for (i; i > -1; i--) if (op12[i] != '0') break; string res = op11 + "." + op12.substr(0, i + 1); cout << res << endl; return 0; }