花了大概三天的零碎时间学习了用栈实现计算器(可用于小数点以及多位数的计算)。下面转来了一篇前人的代码,而且把自己的理解作为注释写入。
. 就目前所学,还写不出其他什么值得记录的东西。先这样O(∩_∩)O
#include <iostream>
#include <string>
#include <stack>
#include<cctype>
using namespace std;
bool IsOne(char c){
return (c == '+' || c == '-');
}
bool IsTwo(char c){
return (c == '*' || c == '/');
}
string Infix_Postfix(string Infix){//中缀改后缀
stack<char> stack;
string result;
for (int i = 0; i<Infix.size(); i++){
if (isdigit(Infix[i]) || Infix[i] == '.')//函数isdigit(), 参数是数字,返回真
{
while (isdigit(Infix[i]) || Infix[i] == '.')
{result += Infix[i++]; }
i--;//while循环最后多加了一次,减回去.*
result += ' '; //不同数字之间用空格隔开
}
else if (IsOne(Infix[i])){ //读到一级运算符
while (stack.size() && (IsOne(stack.top()) || IsTwo(stack.top()))){ //A&&(B||C)形式
result += stack.top();
stack.pop();
}
stack.push(Infix[i]);
}
else if (Infix[i] == ')'){ //括号优先
while (stack.top() != '('){
result += stack.top();
stack.pop();
}
stack.pop();//最后记得弹出"("
}
else if (IsTwo(Infix[i])){ //读到二级运算符
while (stack.size() && IsTwo(stack.top())){
result += stack.top();
stack.pop();
}
stack.push(Infix[i]);//压入二级运算符
}
else stack.push(Infix[i]);
}
while (stack.size()){
result += stack.top();
stack.pop();
}
return result;
}
double TenTimes(int n){
double res = 1;
for (int i = 0; i<n; i++){
res *= 10;
}
return res;
}
double Achieve(string s){ // 实现了大于9以及小数的计算
double res = 0;
char c;
int dec = 0;
for (int i = 0; i < s.size(); i++){
c = s[i ];
if (c == '.') dec = i; //标记小数点在第几位
else if (!dec) res = res * 10 + c - '0';//只要往后一位,前面的计算结果*10
else res += (c - '0') / TenTimes(i-dec);//计算小数值
}
return res;
}
double Calculate(string s){
double res, t;
stack<double> num;
string temp;
for (int i = 0; i<s.size(); i++){
temp = "";
if (isdigit(s[i]) || s[i] == '.'){
while (isdigit(s[i]) || s[i] == '.') temp += s[i++]; //如果最后一位是数字,这样做会出错
num.push(Achieve(temp));
}
else{
switch (s[i]){
case '+': t = num.top(); num.pop(); t += num.top(); num.pop(); num.push(t); break;
case '-': t = num.top(); num.pop(); t = num.top() - t; num.pop(); num.push(t); break;
case '*': t = num.top(); num.pop(); t *= num.top(); num.pop(); num.push(t); break;
case '/': t = num.top(); num.pop(); t = num.top() / t; num.pop(); num.push(t); break;
default: cerr << "Fatal Error! Result would be wrong!" << endl; system("pause"); break;
}
}
}
res = num.top();
return res;
}
int main(){
string mid, result;
cin >> mid;
result = Infix_Postfix(mid);
cout << "Infix change to Postfix: " << endl;
cout << result << endl;
cout << "The result is: " << Calculate(result) << endl;
system("pause");
return 0;
}