您的位置:首页 > 理论基础 > 数据结构算法

<数据结构>栈-表达式求值

2013-06-04 22:11 369 查看
#include <cstdio>
#include <malloc.h>
#include <cstring>
#define MAXSIZE 101

//运算符栈
struct OpStack
{
char data[MAXSIZE];
int top; //栈顶元素下一个元素的下标
};

//初始化运算符栈
OpStack *Init_Op()
{
OpStack *sOp;
sOp = (OpStack *)malloc(sizeof(OpStack));
sOp->top = 0;
return sOp;
}

//入运算符栈
int Push_Op(OpStack *sOp, char ch)
{
if (sOp->top == MAXSIZE)
{
return 0;
}
else
{
sOp->data[sOp->top] = ch;
sOp->top++;
return 1;
}
}

//出运算符栈
int Pop_Op(OpStack *sOp, char *ch)
{
if (sOp->top == 0)
{
return 0;
}
else
{
*ch = sOp->data[sOp->top-1];
sOp->top--;
return 1;
}
}

//获取运算符栈栈顶元素
char GetTop_Op(OpStack *sOp)
{
return sOp->data[sOp->top-1];
}

//判断运算符栈是否为空
int IsEmpty_Op(OpStack *sOp)
{
return sOp->top == 0;
}

//操作数栈
struct NumStack
{
float data[MAXSIZE];
int top; //栈顶元素下一个元素的下标
};

//初始化操作数栈
NumStack *Init_Num()
{
NumStack *sNum;
sNum = (NumStack *)malloc(sizeof(NumStack));
sNum->top = 0;
return sNum;
}

//入操作数栈
int Push_Num(NumStack *sNum, float num)
{
if (sNum->top == MAXSIZE)
{
return 0;
}
else
{
sNum->data[sNum->top] = num;
sNum->top++;
return 1;
}
}

//出操作数栈
int Pop_Num(NumStack *sNum, float *num)
{
if (sNum->top == 0)
{
return 0;
}
else
{
*num = sNum->data[sNum->top-1];
sNum->top--;
return 1;
}
}

//获取操作数栈栈顶元素
float GetTop_Num(NumStack *sNum)
{
return sNum->data[sNum->top-1];
}

//判断操作数栈是否为空
int IsEmpty_Num(NumStack *sNum)
{
return sNum->top == 0;
}

//判断运算符的优先级
int priority(char ch)
{
if (ch=='=' || ch=='(')
{
return 0; //使左括号和等号的优先级最低
}
else if (ch=='+' || ch=='-')
{
return 1;
}
else if (ch=='*' || ch=='/')
{
return 2;
}
}

//计算结果
float result(float x, float y, char ch)
{
if (ch == '+')
{
return y+x;
}
else if (ch == '-')
{
return y-x;
}
else if (ch == '*')
{
return y*x;
}
else if (ch == '/')
{
return y/x;
}
}

//中缀表达式转换为后缀表达式
void toPostfix(char inf[], char post[])
{
//post为存放后缀表达式的字符数组
int index = 0; //用于动态的表示post数组的下标
bool isNum = false; //用于判断之前是否出现过数字
OpStack *sOp; //定义运算符栈
sOp = Init_Op(); //初始化运算符栈
char ch;//接收出栈的左括号

//循环遍历中缀表达式
for (int i=0; i<strlen(inf); i++)
{
//判断是否为数字或者小数点
if (inf[i]>='0' && inf[i]<='9' || inf[i]=='.')
{
isNum = true; //将布尔值置为真
post[index++] = inf[i]; //直接将数字加入到post数组中
}
else
{
//如果输入空格,结束本次循环
if (inf[i] == ' ')
{
continue ;
}

//判断之前是否出现了数字
if (isNum)
{
post[index++] = '#';
isNum = false; //将布尔值置为假
}

//判断是否结束
if (inf[i] == '=')
{
break;
}

//判断是否为'('或者栈空
if (inf[i]=='(' || IsEmpty_Op(sOp))
{
//将其入栈
Push_Op(sOp, inf[i]);
}
else if (inf[i]==')')
{
//循环到左括号
while (GetTop_Op(sOp) != '(')
{
//依次出栈,并加入到post数组中
Pop_Op(sOp, &post[index++]);
}

Pop_Op(sOp, &ch);//将左括号出栈
}
else if (!IsEmpty_Op(sOp) && priority(inf[i])<=priority(GetTop_Op(sOp)))
{
//栈不为空,且此运算符的优先级低于或等于栈顶元素优先级
while (!IsEmpty_Op(sOp) && priority(inf[i])<=priority(GetTop_Op(sOp)))
{
//出栈加post
Pop_Op(sOp, &post[index++]);
}

//循环完毕,把此运算符压入栈中
Push_Op(sOp, inf[i]);
}
else
{
//直接把此运算符压入栈中
Push_Op(sOp, inf[i]);
}
}
}

//遍历完成
//将栈顶运算符出栈,加入到post中
Pop_Op(sOp, &post[index++]);

//字符串末尾加上'\0'
post[index] = '\0';
return ;
}

//计算后缀表达式
float caPostfix(char post[])
{
NumStack *sNum; //定义一个操作数栈
sNum = Init_Num();//初始化操作数栈
float res; //存放结果
bool isPoint;//判断是否有小数点
float pos;//10的倍数
float temp1; //存放操作数1
float temp2;//存放操作数2

for (int i=0; i<strlen(post); i++)
{
res = 0;
isPoint = false;
pos = 10;

//判断是否为数字
if (post[i]>='0' && post[i]<='9')
{
//数字没结束前
for (; post[i]!='#'; i++)
{
if (post[i]=='.')
{
isPoint = true;
i++;
}

//如果没有小数点,整数部分
if (!isPoint)
{
res = res*10+post[i]-'0';
}
else
{
res += (post[i]-'0')/pos;
pos *= 10;
}
}

//把结果入栈
Push_Num(sNum, res);
}
else
{
Pop_Num(sNum, &temp1);//出栈第一个操作数
Pop_Num(sNum, &temp2);//出栈第二个操作数
Push_Num(sNum, result(temp1, temp2, post[i]));//结果入栈
}
}
return GetTop_Num(sNum);
}

int main()
{
printf("|-----------表达式求解----------|\n");
printf("|1.该程序支持浮点数运算         |\n");
printf("|2.该程序支持空格输入           |\n");
printf("|3.该程序支持多重小括号运算     |\n");
printf("|注:此程序使用的是后缀表达式计算|\n");
printf("|-------------------------------|\n");
char inf[MAXSIZE];//定义一个存放中缀表达式的字符数组
printf("请输入你需要计算的中值表达式(eg:(2*(2*(3+1))+1=,注意末尾有一个=号.):\n");
gets(inf);//输入中缀表达式字符数组

char post[MAXSIZE];
toPostfix(inf, post);
printf("Postfix:%s\n", post);

float res;
res = caPostfix(post);
printf("Result:%s%.2f\n", inf, res);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: