栈-表达式求值

/*栈的顺序存储-表达式求值*/
//假设输入字符不超过20个,运算数字都是非负的整数,即0,1,2,,,,等等
//
#include<iostream>
#include<stdlib.h>//为了使用atoi函数,具体函数用法及作用参见百度或C plus plus 网站
using namespace std;
/*
(1+9)*2/2-1=9
(1+9)*2/20-1=0
1+0=1
*/
template<typename T>
struct Stack
{
	T *t;
	T *base;
	T *top;
};
/*1.初始化栈*/
template<typename T>
bool init(Stack<T> &stack)
{
	stack.t = new T[400];//假设运算数和运算符的长度都不超过40
	if (!stack.t) { exit(0); }
	stack.base = stack.top = stack.t;
	return true;
}
/*2.入栈,入栈元素为e*/
template<typename T>
bool push(Stack<T> &stack, T e)
{
	//cout << "入栈" << e << endl;
	*stack.top++ = e;
	return true;
}
/*3.出栈,top指针下移*/
template<typename T>
T pop(Stack<T> &stack)
{
	if (stack.base == stack.top) { cout << "空栈无法出栈操作!\n"; exit(0); }
	T temp = *--stack.top;
	return temp;
}
/*4.返回栈顶元素,栈顶指针不移动*/
template<typename T>
T getTop(Stack<T> &stack)
{
	if (stack.base == stack.top) { cout << "空栈无法操作!\n"; exit(0); }
	return *(stack.top - 1);
}
/*5.返回运算符优先级*/
int getLevel(char &c)
{
	switch (c)
	{
	case '+':
	case '-':return 1;
	case '*':
	case '/':return 2;

	default:return 0;//包括小括号,和#
	}
}
/*6.返回一个整数的位数*/
int getNum(int e)//使用引用要记住引用的数可不可以改变,
{
	int number = 0;
	if (e == 0)//当初没想到这个,导致在输入数据1+0时奔溃了。。。
		return 1;
	while (e != 0)
	{
		number++;
		e = e / 10;
	}
	return number;
}
/*7.四则运算,两个整数通过op运算符进行运算*/
int operate(int &one, char &op, int &two)
{

	switch (op)
	{
	case '+':return one + two;
	case '-':return one - two;
	case '*':return one*two;
	case '/':return one / two;
	}
}
/*8.利用栈求出表达式的最终解,oper是运算符栈,opnd是运算数栈*/
int evaluate(char *p)//不允许使用多个模板作为参数??????
{
	Stack<int> opnd;
	Stack<char> oper;
	init(oper);
	init(opnd);
	push(oper, '#');//参数列表不能为引用,不然报错
	while (*p != '\0')
	{
		/*1*/
		if (*p >= '0'&&*p <= '9')//如果是数字,考虑到数字不一定一位数,所以做特殊处理,转化为正常的数字,压入栈
		{
			int temp = atoi(p);
			p = p + getNum(temp);//此时p指向数字后的第一个非数字
			push(opnd, temp);////////////////////////////////////
		}
		/*2*/
		else if (*p == '(')
		{
			push(oper, '(');
			p++;
		}
		/*3*/
		else if (*p == ')')
		{
			while (getTop(oper) != '(')//while一直找到'(' ; 例如(1+2*3)*5
			{
				char ch = pop(oper);
				int right = pop(opnd);
				int left = pop(opnd);

				int end = operate(left, ch, right);
				push(opnd, end);
			}
			pop(oper);//去掉左括号(
			p++;
		}
		/*4*/
		else //加减乘除四个情况
		{
			char ch = getTop(oper);
			int topLevel = getLevel(ch);

			int currentLevel = getLevel(*p);
			//比较运算符优先级
			if (topLevel < currentLevel)
				push(oper, *p);
			else
			{
				int right = pop(opnd);
				int left = pop(opnd);
				int temp = operate(left, ch, right);

				pop(oper);//ch运算符已使用,需删掉
				push(opnd, temp);//进栈
				push(oper, *p);
			}
			p++;
		}
	}//while (*p != '\0')

	while (getTop(oper) != '#')//做最后处理
	{
		char ch = pop(oper);
		int right = pop(opnd);
		int left = pop(opnd);

		int end = operate(left, ch, right);
		push(opnd, end);
	}
	return getTop(opnd);
}
int main()
{
	//假设输入字符不超过20个,运算数字都是非负的整数,即0,1,2,,,,等等
	char a[400];
	cin >> a;
	cout << evaluate(a) << endl;
	return 0;
}

你可能感兴趣的:(数据结构,C++,c,栈)