中缀表达式转换成后缀表达式 计算后缀表达式的值 幂操作符添加到你的指令系统中去

数据结构与算法分析——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;
}




你可能感兴趣的:(中缀表达式转换成后缀表达式 计算后缀表达式的值 幂操作符添加到你的指令系统中去)