逆波蘭表示式(字尾表示式)的計算
阿新 • • 發佈:2019-02-13
已知12*(3+4)- 6+8/2的字尾表示式為:12 3 4 + * 6 - 8 2 / +
字尾表示式計算時,所有運算按照運算子出現的順序,嚴格從左到右,每個操作符取前兩個運算元進行運算,運算後的結果仍然作為下次的運算元。
那如果已知字尾表示式,如何求值:
具體做法:
程式碼:
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<stdio.h>
//包裝靜態棧
#define MAX 20
typedef struct s
{
int arr[MAX];
int top;
}stack;
//列舉
enum Calc
{
ADD,
SUB,
MUL,
DIV,
DATA
};
//操作
typedef struct operate
{
enum calc op;
int _data;
}operate;
//棧初始化
void StackInit(stack *s);
//棧頂元素
int TopStack(stack *s);
//出棧
void PopStack(stack *s);
//逆波蘭表示式的求解
int CalcRPN(operate *cal, stack *s,int size);
#include"RPN.h"
void TestRPN()
{
int size = 0;
int ret = 0;
stack s;
//定義結構體陣列
operate cal[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, { ADD, 0 }, { MUL, 0 },
{ DATA, 6 }, { SUB, 0 }, { DATA, 8 }, { DATA, 2 }, { DIV, 0 }, { ADD, 0 } };
size = sizeof(cal) / sizeof(cal[0 ]);
//棧初始化
StackInit(&s);
//逆波蘭表示式的求解
ret = CalcRPN(cal,&s,size);
printf("ret = %d\n", ret);
}
int main()
{
TestRPN();
system("pause");
return 0;
}
#include"RPN.h"
//棧初始化
void StackInit(stack *s)
{
assert(s);
s->top = 0;
memset(s->arr, 0, MAX*sizeof(int));
}
//資料入棧
void PushStack(stack *s, int data)
{
assert(s);
if (s->top > MAX)
{
return;
}
s->arr[s->top] = data;
s->top++;
}
//棧頂元素
int TopStack(stack *s)
{
assert(s);
return s->arr[s->top - 1];
}
//出棧
void PopStack(stack *s)
{
assert(s);
s->top--;
}
//逆波蘭表示式的求解
int CalcRPN(operate *cal, stack *s,int size)
{
int i = 0;
int left = 0;
int right = 0;
int ch = 0;
assert(s);
for (i = 0; i < size; i++)
{
if (cal->op == DATA)
{
//資料入棧
PushStack(s,cal->_data);
}
else
{
ch = cal->op;
//棧頂元素
right = TopStack(s);
//出棧
PopStack(s);
left = TopStack(s);
//出棧
PopStack(s);
switch (ch)
{
case ADD:PushStack(s,left + right);
break;
case SUB:PushStack(s, left - right);
break;
case MUL:PushStack(s, left * right);
break;
case DIV:
if (right == 0)
{
printf("除數為0,非法!!!\n");
return 0;
}
else
{
PushStack(s, left / right);
}
break;
default:printf("運算元非法!!\n"); break;
}
}
cal++;
}
return TopStack(s);
}