/*
- 首先声明两类型的栈每个类型两个栈, 其中一个栈存储数值(dptr) 一个用来存临时的运算符的(sptr)
- 当遇到数值的时候 入栈(dptr)
- 当遇到 + - * \ ( 的运算符的时候入栈(sptr)
- 当遇到 ) 的时候 sptr出栈,出栈的结果 入栈(dptr) 直到 出栈得出的结果是( ’(‘ )
- 每次数值入栈后 判断运算符的栈顶符号 如果是 * / 则 出栈出栈结果到(dptr)
最后得到的结果就是 一个反向的 后缀表达式
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef double DateType;
typedef char SymbolType;
typedef struct RpnNode{
SymbolType symol;
DateType data;
struct RpnNode *next;
}RpnNode, *RpnNodeList;
typedef struct RpnNodeSave{
RpnNodeList top;
RpnNodeList base;
int count;
}RpnNodeSave;
// 数据进站
void Push(RpnNodeSave *L, DateType data){
RpnNode *node, *top;
top = L->top;
node = (RpnNode *)malloc(sizeof(RpnNode));
node->data = data;
node->next = top;
L->top = node;
L->count++;
}
// 运算符进站
void symbolPush(RpnNodeSave *L, SymbolType symol){
RpnNode *node, *top;
top = L->top;
node = (RpnNode *)malloc(sizeof(RpnNode));
node->symol = symol;
node->next = top;
L->top = node;
L->count++;
}
// 数值出站
void Pop(RpnNodeSave *ptr, DateType *e){
RpnNode *node, *topnext;
node = ptr->top;
*e = node->data;
topnext = node->next;
free(node);
ptr->top = topnext;
ptr->count--;
}
// 运算符出站
void symbolPop(RpnNodeSave *ptr, SymbolType *e){
RpnNode *node, *topnext;
node = ptr->top;
*e = node->symol;
topnext = node->next;
free(node);
ptr->top = topnext;
ptr->count--;
}
// 打印值
void printStack(RpnNode *L){
while(L->next){
printf("(%f:%c)->", L->data, L->symol);
L = L->next;
}
printf("\n");
}
char saveData(RpnNodeSave *dptr, char *data){
int i = 0;
char str[10];
DateType store;
while(isdigit(*data) || '.' == *data){
str[i++] = *data;
str[i] = '\0';
if (i >= 10){
printf("输入的单个数据过大\n");
return '#';
}
scanf("%c", data);
if(!isdigit(*data) && '.' != *data){
store = atof(str);
Push(dptr, store);
i = 0;
return *data;
}
}
}
int main(int argc, char const *argv[])
{
char data, tmp;
int err = 0, i = 0;
DateType start, end, result, store;
// 数值的栈值
RpnNode *dHead, *tmpStruct, *tmpNode, *tmpNext;
dHead = (RpnNodeList)malloc(sizeof(RpnNode));
dHead->next = NULL;
// 数值统计的栈值
RpnNodeSave *dptr;
dptr = (RpnNodeSave *)malloc(sizeof(RpnNodeSave));
dptr->top = dHead;
dptr->base = dHead;
dptr->count = 0;
// 符号的栈值
RpnNode *sHead, *tmpTop;
sHead = (RpnNodeList)malloc(sizeof(RpnNode));
sHead->next = NULL;
// 符号统计的栈值
RpnNodeSave *sptr;
sptr = (RpnNodeSave *)malloc(sizeof(RpnNodeSave));
sptr->top = sHead;
sptr->base = sHead;
sptr->count = 0;
printf("请输入一串后缀表达式, 以Enter结束: \n");
scanf("%c", &data);
while(data != '\n'){
saveData(dptr, &data);
tmpTop = sptr->top;
tmp = tmpTop->symol;
if(tmp == '*' || tmp == '/'){
symbolPop(sptr, &tmp);
symbolPush(dptr, tmp);
}
if(data == '+' || data == '-' ||
data == '*' ||
data == '/' ||
data == '('){
symbolPush(sptr, data);
}
if(data == ')'){
while(1){
symbolPop(sptr, &tmp);
if(tmp == '('){
break;
}
symbolPush(dptr, tmp);
}
}
scanf("%c", &data);
}
tmpStruct = sptr->top;
while(tmpStruct->next){
symbolPush(dptr, tmpStruct->symol); // 栈 1
tmpStruct = tmpStruct->next;
}
printStack(dptr->top);
// 开始按照逆波兰计算结果
RpnNode *caclHead;
caclHead = (RpnNodeList)malloc(sizeof(RpnNode));
caclHead->next = NULL;
tmpStruct = (RpnNodeList)malloc(sizeof(RpnNode));
tmpStruct->next = NULL;
// 数值统计的栈值
RpnNodeSave *cptr;
cptr = (RpnNodeSave *)malloc(sizeof(RpnNodeSave));
cptr->top = caclHead;
cptr->base = caclHead;
cptr->count = 0;
tmpNode = dptr->top;
while(tmpNode->next){
tmpNext = tmpNode->next;
tmpNode->next = tmpStruct;
tmpStruct = tmpNode;
tmpNode = tmpNext;
}
while(tmpStruct->next){
data = tmpStruct->symol;
switch(data){
case '+':
Pop(cptr, &end);
Pop(cptr, &start);
Push(cptr, start + end);
break;
case '-':
Pop(cptr, &end);
Pop(cptr, &start);
Push(cptr, start - end);
break;
case '*':
Pop(cptr, &end);
Pop(cptr, &start);
Push(cptr, start * end);
break;
case '/':
Pop(cptr, &end);
Pop(cptr, &start);
if(end == 0){
printf("输入错误,除数不能为0\n");
return -1;
}
Push(cptr, start / end);
break;
default:
Push(cptr, tmpStruct->data);
}
tmpStruct = tmpStruct->next;
}
Pop(cptr, &result);
printf("result: %f \n", result);
getchar();
return 0;
}
请输入一串后缀表达式, 以Enter结束:
1+(2-3)*4+10/5+10
(0.000000:+)->(0.000000:+)->(0.000000:+)->(10.000000:)->(0.000000:/)->(5.000000:)->(10.000000:)->(0.000000:*)->(4.000000:)->(0.000000:-)->(3.000000:)->(2.000000:)->(1.000000:)->
result: 9.000000