利用栈计算算数表达式的值

先将中缀表达式利用栈转换为后缀表达式,然后再利用栈由后缀表达式计算算数表达式的值,具体代码如下:

#include <iostream>
using namespace std;

#include <string>
#include <vector>
#include <stack>

enum Type
{
	OP_NUM,
	OP_SYMBOL,
};

enum Operat
{
	ADD,
	SUB,
	MUL,
	DIV,
};

struct Cell
{
	Type _type;
	int _num;
};

//input = 1 + ((2 + 3) * 4) - 5;

//中缀到后缀
string topolishNotation(const char* input)
{
	stack<char> s1; //运算符
	stack<char> s2; //数字
	size_t iCount = 0;
	while (input[iCount] != ‘\0‘)
	{
		//是数字将其压入s2
		if (input[iCount] >= ‘0‘&& input[iCount] <= ‘9‘)
		{
			while (input[iCount] != ‘\0‘ && input[iCount] >= ‘0‘&& input[iCount] <= ‘9‘)
			{
				s2.push(input[iCount++]);
			}
			s2.push(‘ ‘);
			--iCount; //最后会统一加1,所以先减一
		}

		//是运算符比较其与S1栈顶运算符的优先级
		while (input[iCount] == ‘+‘ || input[iCount] == ‘-‘ ||
			input[iCount] == ‘*‘ || input[iCount] == ‘/‘)
		{
			//s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈
			if (s1.empty() || s1.top() == ‘(‘)
			{
				s1.push(input[iCount]);
				break;
			}
			//否则,若优先级比栈顶运算符的高,也将运算符压入s1
			else if ((input[iCount] == ‘*‘ || input[iCount] == ‘/‘) &&
				(s1.top() == ‘+‘ || s1.top() == ‘-‘))
			{
				s1.push(input[iCount]);
				break;
			}
			//否则,将S1栈顶的运算符弹出并压入到S2中,再次与S1中新的栈顶运算符相比较
			else
			{
				s2.push(s1.top());
				s1.pop();
			}
		}

		//如果是左括号“(”,则直接压入S1;
		if (input[iCount] == ‘(‘)
		{
			s1.push(input[iCount]);
		}

		/*如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,
		*直到遇到左括号为止,此时将这一对括号丢弃;*/
		if (input[iCount] == ‘)‘)
		{
			while (s1.top() != ‘(‘)
			{
				s2.push(s1.top());
				s1.pop();
			}
			s1.pop(); //将‘(‘也出栈
		}

		++iCount; //统一加一次
	}

	//将S1中剩余的运算符依次弹出并压入S2;
	while (!s1.empty())
	{
		s2.push(s1.top());
		s1.pop();
	}

	string ret;
	while (!s2.empty())
	{
		ret.push_back(s2.top());
		s2.pop();
	}
	reverse(ret.begin(), ret.end());
	return ret;
}

//后缀到数组
vector<Cell> StrBehindToVect(const string& strBehind)
{
	vector<Cell> call;
	size_t iCount = 0;
	while (strBehind[iCount] != ‘\0‘)
	{
		if (strBehind[iCount] >= ‘0‘ && strBehind[iCount] <= ‘9‘)
		{
			int ret = 0;
			while (strBehind[iCount] != ‘\0‘ && strBehind[iCount] >= ‘0‘ && strBehind[iCount] <= ‘9‘)
			{
				ret = ret * 10 + strBehind[iCount] - ‘0‘;
				++iCount;
			}
			call.push_back({ OP_NUM, ret });
			--iCount;
		}
		else if (strBehind[iCount] == ‘+‘)
		{
			call.push_back({ OP_SYMBOL, ADD });
		}
		else if (strBehind[iCount] == ‘-‘)
		{
			call.push_back({ OP_SYMBOL, SUB });
		}
		else if (strBehind[iCount] == ‘*‘)
		{
			call.push_back({ OP_SYMBOL, MUL });
		}
		else if (strBehind[iCount] == ‘/‘)
		{
			call.push_back({ OP_SYMBOL, DIV });
		}
		++iCount;
	}
	return call;
}

//计算值
int RPNCount(const vector<Cell>& array, size_t size)
{
	stack<int> val;
	for (size_t i = 0; i < size; ++i)
	{
		if (array[i]._type == OP_NUM)
		{
			val.push(array[i]._num);
		}
		else
		{
			int right = val.top();
			val.pop();
			switch (array[i]._num)
			{
			case ADD:
				val.top() += right;
				break;
			case SUB:
				val.top() -= right;
				break;
			case MUL:
				val.top() *= right;
				break;
			case DIV:
				if (right == 0)
				{
					throw(array[i]);
				}
				val.top() /= right;
				break;
			default:
				cout << "请输入合法字符" << endl;
				exit(0);
			}/*switch*/
		}
	}
	return val.top();
}

int main()
{
	string strMid = "12 * (3 + 4) - 6 + 8 / 2";
	string strBehind = topolishNotation(strMid.c_str());
	vector<Cell> call = StrBehindToVect(strBehind);
	try
	{
		int ret = RPNCount(call, call.size());
		cout << ret << endl;
	}
	catch (Cell)
	{
		cout << "除数为0!" << endl;
	}
	system("pause");
	return 0;
}
时间: 2024-10-25 08:25:46

利用栈计算算数表达式的值的相关文章

Python解析 算数表达式求值 栈的使用

使用Python实现一种算数表达式求值的算法,模拟这种使用栈的方式,这是由E.W.Dijkstra在20世纪60年代发明的一种非常简单的算法.代码模拟仅仅表现一种编程思想,代码的逻辑并不完全: if __name__ == "__main__": cal_str = input("请输入算数表达式(e.g.(((1+2)*(3+5))+2), 只适合简单的算数表达式):") num_stack = [] symbol_stack = [] for chr in ca

栈应用二(表达式求值)

问题;设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值.(1)输入的形式:表达式,例如3+2*6-4     包含的运算符只能有'+' .'-' .'*' .'/'(目前还不兼容括号) :(2)输出的形式:运算结果,例如3+2*6-4=11: (3)程序所能达到的功能:对表达式求值并输出:示例:①3+2*6-4 ②30+20*6-80 ③2*7-3*5-3 思路:1.程序扫描表达式,一个一个的扫描2.当发现这个字符是数字的时候,直接入数栈

使用E.W.D.Dijkstra设计算法实现算数表达式求值

要求:编程模拟(1+(2+3)*(4*5))的运算过程,重点在于如何解析由括号运算符和数字组成的字符串,并按照正确的顺序完成各种初级运算符的操作. 实现思路:用两个栈(LIFO)结构来实现(一个用于保存运算符,一个用于保存操作数) 将操作数压如操作数栈 将操作符压如操作符栈 忽略左括号 在遇到右括号时,弹出一个运算符,并弹出所需数量的操作数,并将操作符和操作数的运算结果压到操作数栈 1 package com.luochuang.demo.stdlib; 2 3 public class Eva

计算字符串表达式的值

一.题目描述 给你一个字符串,包含+,-,*,/和(),数字为0-9,让计算该表达式的值,例如"1+2*3-(8/4)+6",结果为11,这是前几天面试去哪儿网,二面面试官让手撕的题目.记忆中本科的时候遇到过,当时也没啥思路.其实这个题需要分两步完成,第一步:把字符串表达式的中缀形式转为后缀形式,怎么转有一定的规则.第二步:计算后缀表达式的值. 关于什么是前缀,中缀,后缀表达式,请读者自己查阅资源,这里就不介绍了.我们只谈如何从中缀转为后缀,规则如下: 首先定义一个栈stack用来保存

数据结构 栈的应用 --表达式求值

一: 中缀表达式求值  思想: 需要2个栈,运算对象栈OPND,运算符栈OPTR, 1:将栈OPND初始化为空,栈OPTR初始化为表达式的定界符# 2:扫描表达式,直到遇到结束符# 2.1:当前字符是运算对象,入栈OPND 2.2:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级高,入栈OPTR,处理下一个字符 2.3:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级低,则从栈OPND出栈2个运算对象,从栈OPTR出栈一个运算符进行运算,并将运算结果入栈OPND,处理当前字符 2.4

栈的应用——表达式求值

表达式求值是程序设计语言编译中的一个基本问题,它的实现就是对“栈”的典型应用.本文针对表达式求值使用的是最简单直观的算法“算符优先法”. 本文给出两种方式来实现表达式求值,方式一直接利用中缀表达式求值,需要用到两个栈,操作数栈和操作符栈.首先置操作数栈为空栈, 操作符栈仅有“#”一个元素.依次读入表达式中的每个字符,若是操作数则进操作数栈,若是操作符则和操作符栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕.方式二首先把中缀表达式转换为后缀表达式并存储起来,然后利用读出的后缀表达式完成

利用栈求逻辑运算表达式的真值

今天浙江理工校赛的D题. 比赛结束后在网上看了文章才做出来的. Problem D: 逻辑运算 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 248  Solved: 36 Description 还记得大学里学过的模电么,今天就让我们将与或非变成一道题吧. 给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符. 三种逻辑运算符按照优先级排列如下. '!':表示取反. '&':逻辑与. '|':逻辑或. 两个字符'T','F'分别表示

NYOJ--128--前缀式计算(表达式求值)

前缀式计算 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 先说明一下什么是中缀式: 如2+(3+4)*5这种我们最常见的式子就是中缀式. 而把中缀式按运算顺序加上括号就是:(2+((3+4)*5)) 然后把运算符写到括号前面就是+(2 *( +(3 4) 5) ) 把括号去掉就是:+ 2 * + 3 4 5 最后这个式子就是该表达式的前缀表示. 给你一个前缀表达式,请你计算出该前缀式的值. 比如: + 2 * + 3 4 5的值就是 37 输入 有多组测试数据,每

双栈计算算术表达式

1.介绍 算术表达式的计算,是比较常见的问题,但这个问题的背后隐藏着栈的思想. 这里就介绍使用两个栈来计算表达式的方法. 2. 算法 2.1 定义: a) 建立两个栈: 一个是数据栈dataStak,用于存放数据: 一个是符号栈operatorStack,用于存放运算符: b) 建立运算符号之间的优先级表,用于比较两个符号之间的优先级: 优先级定义为三种运算结果:>(表示高于),<(表示低于),=(表示相等): 并且对于"("与")",认为两者的优先级相