数据结构与算法分析——c语言描述 练习3.19 3.20 a b 答案
这道题以前发过文章。现在能支持幂^了。
栈的利用
挺重要的一个思想是 操作符 根据优先级分级
再次更新
1.支持+ - * / ^
2.支持括号
3.支持括号前后省略*,例如5(4)5=100
4.支持小数点
#include<stack> #include<stdio.h> #include<ctype.h> #include<string> #include<map> using namespace std; #define MAXN 100 char expression[MAXN];//输入的表达式 string postfix[MAXN];//转换成的逆序表达式 int i = 0, j = 0;//i是expression的游标,postfix是逆序表达式的游标 map<char, double(*)(double, double)> operaFunc;//运算符字符与运算函数的映射 double _add(double x, double y) { return x + y; } double _sub(double x, double y) { return x - y; } double _mul(double x, double y) { return x * y; } double _div(double x, double y) { return x / y; } double _power(double x, double n) {//计算幂次方 double ans = 1; for (double i = 0; i < n; i++) ans *= x; return ans; } double operatorCmp(char c1, char c2);//c1为将要插入栈的运算符,c2为栈顶运算符,1表示c1优先级大于c2,0为相等,-1为小于 #define putNum() postfix[j++] = num,num.clear();//把数字输出到逆序表达式 #define putOperator() oper= operator_stack.top(),operator_stack.pop(),postfix[j++] = oper;//把符号输出到逆序表达式 double operatorPriority(char c) {//运算符优先级比较 if (c == '^') return 3; else if (c == '*' || c == '/') return 2; else if (c == '+' || c == '-') return 1; } void ProcessingOperator(char &c,char &oper,string &num, stack<char>&operator_stack) {//i指向的表达是为运算符字符处理 if (!num.empty()) putNum(); if (operator_stack.empty()) operator_stack.push(c); else if (operatorCmp(c, operator_stack.top()) >0) { operator_stack.push(c); } else { while (1) { putOperator(); if (operatorCmp(c, oper) >0 || operator_stack.empty()) { operator_stack.push(c); break; } } } } int midToPostfix() {//中缀转后缀,返回int是指括号后面是否直接是数字 int flag = 0; stack<char>operator_stack; string num; char c, oper; for (; expression[i] != '\0'; i++) { c = expression[i]; if (c == '(') { if (isdigit(expression[i - 1]) || expression[i - 1] == ')')//遇到3(4)(3)的情况,要在括号前自行处理省去的* { c = '*'; ProcessingOperator(c, oper, num, operator_stack); } i++; if (midToPostfix())//处理(4)4的情况 { c = '*'; ProcessingOperator(c, oper, num, operator_stack); } continue; } else if (c == ')') { if (isdigit(expression[i + 1])) flag = 1; break; } else if (isdigit(c)||c=='.') num += c; else {//运算符 ProcessingOperator(c, oper, num, operator_stack); } } if (!num.empty())//处理表达式最后的数字 postfix[j++] = num; while (!operator_stack.empty()) {//处理留在栈的运算符 postfix[j++] = operator_stack.top(); operator_stack.pop(); } if (flag) return 1; else return 0; } double calculatePostfix() { stack<double>num_stack; double x, y, ans; operaFunc['+'] = _add;//添加映射 operaFunc['-'] = _sub; operaFunc['*'] = _mul; operaFunc['/'] = _div; operaFunc['^'] = _power; for (i = 0; i < j; i++) { if (isdigit(postfix[i][0])) num_stack.push(stod(postfix[i])); else {//运算符 y = num_stack.top(); num_stack.pop(); x = num_stack.top(); num_stack.pop(); ans = operaFunc[postfix[i][0]](x, y); num_stack.push(ans); } } return num_stack.top(); } int main() { scanf("%s", expression); midToPostfix(); for (int i = 0; i < j; i++) { printf("%s", postfix[i].c_str()); } printf("\n"); printf("%.3lf", calculatePostfix()); } double operatorCmp(char c1, char c2) { double t1, t2; t1 = operatorPriority(c1); t2 = operatorPriority(c2); return t1 - t2; }