/*栈的顺序存储-表达式求值*/
//假设输入字符不超过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;
}
栈-表达式求值
最新推荐文章于 2024-08-10 16:43:58 发布