利用堆栈 多项式 转后缀式

参考严蔚敏、吴伟民版《数据结构-C语言版》算法3-3(P52页)所介绍的——利用堆栈求解表达式值(一)

多项式后缀式的算法与程序源码

#+-*/%()(井号、加、减、乘、除、括号)字符堆栈 外的优先级函数定义:

char inStackWeight(char ch) {
	switch (ch)
	{
	case '#':
		return 0;
		break;
	case '(':case '(':
		return 1;
		break;
	case ')':case ')':
		return 6;
		break;
	case '+':case '-':
		return 3;
		break;
	case '*':case '/':case '%':
		return 5;
		break;
	default:
		return 100;
		break;
	}
}

#+-*/%()(井号、加、减、乘、除、括号)字符堆栈 内的优先级函数:

char outStackWeight(char ch) {
	switch (ch) {
	case '#':
		return 0;
		break;
	case '('://case '(':中文字符不是一个字节
		return 6;
		break;
	case ')':
		return 1;
		break;
	case '+':case '-':
		return 2;
		break;
	case '*':case '/':case '%':
		return 4;
		break;
	default:
		return 100;
		break;
	}
}

单字节数字与符号判断函数定义:

char checkNumAndSymbol(char ch) {
	switch (ch)
	{
	case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9'://数字0-9
		return 1;
		break;
	case '(':case ')':case '+':case '-':case '*':case '/':case '%'://运算符
		return 2;
		break;
	default://其他
		return 0;
		break;
	}
}

单字节字符的在堆栈的转置函数定义:

stack<char> reverseCharStack(stack<char> input) {
	stack<char> result;
	while (!input.empty()) {
		result.push(input.top());
		input.pop();
	}
	return result;
}

后缀式转换,重要函数的定义:

分为运算符和其他字符,通过出入堆栈将普通的表达式转成后缀式。

(eg:原表达式:a*b+(c-d/e)*f  ,输出其后缀式为:ab*cde/-f*+   。)

void change2SuffixForm(stack<char> &input) {//input输入:第一个字符在堆栈顶
	stack<char> tempSk;
	stack<char> symbolSk;

	int inTp = 0;
	symbolSk.push('#');//一定要加字符'#'作为参照
	while (!input.empty()) {
		inTp = input.top();
		if (checkNumAndSymbol(inTp)==2) {//符号
			if (outStackWeight(inTp)==1) {//如果是右括号')'
				while (!symbolSk.empty())
				{
					if (outStackWeight(symbolSk.top()) == 6) {//如果是左括号'('
						symbolSk.pop();//出栈
						break;//退出循环
					}
					tempSk.push(symbolSk.top());
					symbolSk.pop();
				}
			}else if (outStackWeight(inTp)<inStackWeight(symbolSk.top())) {//从符号堆栈中弹出到result
				tempSk.push(symbolSk.top());
				symbolSk.pop();
				//把tempSk新弹出来的符号压入符号堆栈
				symbolSk.push(inTp);
			}
			else {
				symbolSk.push(inTp);
			}
		}
		else {//数字
			tempSk.push(inTp);
		}
		input.pop();
	}
	while (!symbolSk.empty()) {//将剩余的运算符出栈
		if(symbolSk.top()!='#')
			tempSk.push(symbolSk.top());
		symbolSk.pop();
	}
	while (!tempSk.empty()) {
		input.push(tempSk.top());
		tempSk.pop();
	}
}

最后是测试这个算法的主函数,为使得函数更具通用性,这里将输入和算法主体函数分离。

测试:

int main(void){
	/*例:
	输入:1*2+(3-4/5)*6
    输出:12*345/-6*+
	*/
	stack<char> result;
	stack<char> finalResult;
	char ch;

	while ((ch = getchar()) != '\n' && (ch != EOF)) {//通过回车结束表达式的输入
			result.push(ch);
	}
	finalResult = reverseCharStack(result);//让最先输入的字符位于堆栈顶
	change2SuffixForm(finalResult);
	while (!finalResult.empty()) {
		printf("%c",finalResult.top());
		finalResult.pop();
	}
	system("pause");
    return 0;
}

结果:

转载于:https://my.oschina.net/panquanxing/blog/1929291

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值