#include "stdafx.h"
#include "dsptdef.h"
#include "util.h"
#include "stack.h"
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
/*数据栈*/
struct OPND //struct结构体构建栈
{
int data[100];
int top;
};
/*符号栈*/
struct OPTR
{
char symbol[100];
int top;
};
void InitOperateNum(struct OPND *StackNum) //数据栈非空
{
StackNum->top = -1;
}
void InitOperateSymbol(struct OPTR *StackSymbol) //符号栈非空
{
StackSymbol->top = -1;
}
/*存入数据栈*/
void InOPND(struct OPND *StackNum, int num)
{
StackNum->top ++;
StackNum->data[StackNum->top] = num;
}
/*存入符号栈*/
void InOPTR(struct OPTR *StackSymbol, char ch)
{
StackSymbol->top ++;
StackSymbol->symbol[StackSymbol->top] = ch;
}
/*读取数据栈*/
int RandOPND(struct OPND *StackNum)
{
return StackNum->data[StackNum->top];
}
/*读取符号栈*/
char RandOPTR(struct OPTR *StackSymbol)
{
return StackSymbol->symbol[StackSymbol->top];
}
/*从数据栈取出数据*/
int PutOPND(struct OPND *StackNum)
{
int x;
x = StackNum->data[StackNum->top];
StackNum->top --;
return x;
}
/*从符号栈取出符号*/
char PutOPTR(struct OPTR *StackSymbol)
{
char c;
c = StackSymbol->symbol[StackSymbol->top];
StackSymbol->top --;
return c;
}
//优先级函数
int precede(char ch)
{
if(ch == '(')
{
return 1;
}
if(ch == '+' || ch == '-') {
return 2;
}
else if(ch == '*' || ch == '/') {
return 3;
}
else if(ch == ')') {
return 4;
}
}
//加减乘除
int Operate(int v1, int v2, char c)
{
int sum;
switch(c) {
case '+' : {
sum = v1 + v2;
break;
}
case '-' : {
sum = v1 - v2;
break;
}
case '*' : {
sum = v1 * v2;
break;
}
case '/' : {
sum = v1 / v2;
break;
}
}
return sum;
}
Status EvaluateExpression(const char* s, int &reasult)
{
struct OPND data;
struct OPTR symbol;
InitOperateNum(&data); //调用数据
InitOperateSymbol(&symbol); //调用符号
int i, t, sum, v1, v2;
i = t = sum = 0;
char v[100] = {0};
char *str = (char *)malloc(sizeof(char)*200); //非空字符
strcpy(str, s);//将表达式存入数组str
for(i = 0; str[i] != '\0'; i ++) {
if(i == 0 && str[i] == '-') {
v[t++] = str[i];
}
else if(str[i] == '(' && str[i+1] == '-') {
i ++;
v[t++] = str[i++];
while(str[i] >= '0' && str[i] <= '9') {
v[t] = str[i];
t ++;
i ++;
}
InOPND(&data, atoi(v));
while(t > 0) {
v[t] = 0;
t --;
}
if(str[i] != ')') {
i --;
InOPTR(&symbol, '(');
}
}
else if(str[i] >= '0' && str[i] <= '9') {
while(str[i] >= '0' && str[i] <= '9') {
v[t] = str[i];
t ++;
i ++;
}
InOPND(&data, atoi(v));
while(t > 0) {
v[t] = 0;
t --;
}
i --;
}
else {
if(symbol.top == -1)
{ //如果符号栈没有元素,直接把符号放入符号栈
InOPTR(&symbol, str[i]);
}
else if(precede(str[i]) == 1) { //如果此符号是'(',直接放入符号栈
InOPTR(&symbol, str[i]);
}
else if(precede(str[i]) == 2) { //如果此符号是'+'或'-',判断与栈顶符号是优先级
if(precede(RandOPTR(&symbol)) == 1) { //如果栈顶符号是'(',放入符号栈
InOPTR(&symbol, str[i]);
}
else if(precede(RandOPTR(&symbol)) == 2) { //如果栈顶符号是'+'或'-',则出栈运算
while(symbol.top >= 0 && data.top >= 1) { //循环出栈
v2 = PutOPND(&data);
v1 = PutOPND(&data);
sum = Operate(v1, v2, PutOPTR(&symbol));
InOPND(&data, sum); //将运算结果压入数据栈
}
InOPTR(&symbol, str[i]); //新符号进栈
}
else if(precede(RandOPTR(&symbol)) == 3) { //如果栈顶符号是'*'或'/',则进符号栈
while(symbol.top >= 0 && data.top >= 1) { //循环出栈
v2 = PutOPND(&data);
v1 = PutOPND(&data);
sum = Operate(v1, v2, PutOPTR(&symbol));
InOPND(&data, sum); //将运算结果压入数据栈
}
InOPTR(&symbol, str[i]); //新符号进栈
}
/*栈顶符号不可能是')',故不做判断*/
}
else if(precede(str[i]) == 3) { //如果此符号是'*'或'/',则判断与栈顶符号是优先级
if(precede(RandOPTR(&symbol)) == 1) { //如果栈顶符号是'(',放入符号栈
InOPTR(&symbol, str[i]);
}
else if(precede(RandOPTR(&symbol)) == 2) { //如果栈顶符号是'+'或'-',则进符号栈
InOPTR(&symbol, str[i]); //新符号进栈
}
else if(precede(RandOPTR(&symbol)) == 3) { //如果栈顶符号是'*'或'/',则出栈运算
while(symbol.top >= 0 && data.top >= 1) { //循环出栈
v2 = PutOPND(&data);
v1 = PutOPND(&data);
sum = Operate(v1, v2, PutOPTR(&symbol));
InOPND(&data, sum); //将运算结果压入数据栈
}
InOPTR(&symbol, str[i]); //新符号进栈
}
}
else if(precede(str[i]) == 4) { // 如果此符号是')',则出栈运算直到遇到'('
do { //循环出栈直到遇到'('
v2 = PutOPND(&data);
v1 = PutOPND(&data);
sum = Operate(v1, v2, PutOPTR(&symbol));
InOPND(&data, sum); //将运算结果压入数据栈
}while(precede(RandOPTR(&symbol)) != 1);
PutOPTR(&symbol); //括号内运算结束后使'('出栈
}
}
}
free(str); //释放数组空间
while(symbol.top != -1) {
v2 = PutOPND(&data);
v1 = PutOPND(&data);
sum = Operate(v1, v2, PutOPTR(&symbol));
InOPND(&data, sum);
}
reasult=(data.data[0]);
return OK;
}