表达式的计算--栈

这篇博客介绍了使用C++实现表达式求值的方法,通过运算符栈和运算数栈来处理运算优先级。程序首先读取输入的表达式,然后将数字压入运算数栈,遇到运算符时比较其优先级,根据优先级决定是否进行运算。同时,还实现了栈溢出处理,确保了大表达式的计算能力。
摘要由CSDN通过智能技术生成

在这里插入图片描述
这里的蓝色符号表示运算符栈中当前存的字符,
紫色表示表达式里的字符。

mysteck.h

#pragma once
#include <iostream>
using namespace std;
template<class T>
class Stack
{
private:
	T* element;
	int top;
	int maxSize;
	void overflowProcess();   //栈的溢出处理
public:
	Stack(int sz = 50);
	~Stack();
	void Push(T x);
	bool Pop(T& x);
	bool getTop(T& x);
	bool Isempty()const { return top == -1; }
	bool Isfull()const { return top == maxSize - 1; }   //比较是否栈顶指针移到最后
};
template<class T>
Stack<T>::Stack(int sz) :maxSize(sz)
{
	top = -1;
	element = new T[maxSize];
	for (int i = 0; i < maxSize; i++)
	{
		element[i] = 0;
	}
}
template<class T>
Stack<T>::~Stack()
{
	delete[]element;
}
template<class T>
void Stack<T>::overflowProcess()
{
	T* newarray = new T[2 * maxSize];
	for (int i = 0; i < maxSize; i++)
	{
		newarray[i] = element[i];
	}
	delete[]element;
	maxSize = maxSize + maxSize;
	element = newarray;
}
template<class T>
void  Stack<T>::Push(T x)
{
	if (Isfull())  overflowProcess();
	//top++;
	//element[top] = x;
	element[++top] = x;
}
template<class T>
bool Stack<T>::Pop(T& x)  //带回值
{
	if (Isempty() == true) return false;
	x = element[top];
	top--;
	return true;
}
template<class T>
bool Stack<T>::getTop(T& x)
{
	if (Isempty() == true) return false;              
	x = element[top];                                          
	return true;                           
}

int isp(char n)
{
	if (n == '#')return 0;
	if (n == '(')return 1;
	if (n == '*')return 5;
	if (n == '/')return 5;
	if (n == '%')return 5;
	if (n == '+')return 3;
	if (n == '-')return 3;
	if (n == ')')return 6;
	return 0;
}
int icp(char n)
{
	if (n == '#')return 0;
	if (n == '(')return 6;
	if (n == '*')return 4;
	if (n == '/')return 4;
	if (n == '%')return 4;
	if (n == '+')return 2;
	if (n == '-')return 2;
	if (n == ')')return 1;
	return 0;
}
bool isDig(char n)
{
	if ('0' <= n && n <= '9')return true;
	return false;
}


int compute(int num1, char sign,  int num2)
{
	int sum=0;
	switch (sign)
	{
	case'+':  sum=num1 + num2; break;
	case'-':  sum = num1 - num2; break;
	case'*':  sum = num1 * num2; break;
	case'/':  sum = num1 / num2; break;
	}
	return sum;
}

主程序.cpp

#include <iostream>
#include <string>
#include "mysteck.h"
using namespace std;
int main()
{
	Stack <int> stacknum;   //运算数栈
	Stack <char> stackchar;  //运算符栈
	char arr[80];    
	int num1 = 0,num2=0;      //从栈中取两个数字进行计算
	char c, m, g ;             //c, m g 负责记录取的栈顶的字符
	int sum = 0;
	int newnum = 0;        //保存计算得到的新的值

	cin.getline(arr, '\n'); //输入表达式
	stackchar.Push('#');    //先在运算符栈中保存“#”,最后能够结束。
	int sz = 0;
	while (arr[sz] != '#'){   
		sz++;
	}
	int count=0;
	char ch = arr[count];           //从头开始记录 字符,根据count 的值不同逐个往后取字符
	do {
		if (isDig(arr[count]))        //运算数的记录    压入运算数栈  //isDig 是判断是否是 数字
		{
			sum = 0;
			while (isDig(arr[count]))
			{
				sum = sum * 10 + arr[count] - '0';
				ch = arr[++count];
				if (isDig(arr[count]) != true)
				{
					stacknum.Push(sum);
					break;
				}
			}
		}
		else  //运算符栈,压入运算符栈
		{
			stackchar.getTop(c);//从栈中取运算符
			int judge = icp(arr[count])- isp(c) ;
			if (judge > 0)
			{ 
				//栈顶的c 优先级低于 输入的 字符数组里的字符的  则压入栈
				ch = arr[count++];
				stackchar.Push(ch); 
			}   
			else if (judge<0)
			{
				stackchar.Pop(m); 
				stacknum.Pop(num1);
				stacknum.Pop(num2);
				newnum = compute(num2, m, num1);
				stacknum.Push(newnum);
			}
			else
			{
				if (ch == ')')          //这里如果是‘)’ 则 把 ‘(’一起弹出 
				{
					stackchar.Pop(m);             
				}
				ch = arr[++count];
			}
		}
		stackchar.getTop(g);
	} while (ch != '#' || g != '#');	
	cout << newnum << endl;
		return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值