后缀(逆波兰)表示法定义:
一种不需要括号的后缀表达法,我们把它称为逆波兰(Reverse Polish Notation ,RPN )表示。
像“9+(3-1)*3+10/2”用后缀表示法应该是“9 3 1 - 3 * + 10 2 / +”,之所以叫后缀表达式就是因为所有的符号都是在运算数字的后面出现
后缀表达式转中缀表达式:
从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即称为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是有括号或者优先级不高于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出到后缀表达式为止。
后缀表达式计算结果:
从从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到是符号,就将处于栈顶的两个数字出栈,进行运算,运算结果出栈,一直到最终获得结果。
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
int InitStack(Stack **s)
{
(*s) = (Stack *)malloc(sizeof(Stack));
if (NULL == *s)
{
return FAILURE;
}
(*s)->length = 0;
(*s)->top = NULL;
return SUCCESS;
}
int EmptyStack(Stack *s)
{
return (NULL == s->top) ? SUCCESS : FAILURE;
}
int Push(Stack *s, DataType e)
{
if (NULL == s)
{
return FAILURE;
}
Node *p = (Node *)malloc(sizeof(Node));
if (NULL == p)
{
return FAILURE;
}
p->data = e;
p->next = s->top;
s->top = p;
s->length++;
return SUCCESS;
}
int LengthStack(Stack *s)
{
return s->length;
}
DataType GetTop(Stack *s)
{
if (NULL == s->top)
{
return FAILURE;
}
return (s->top->data);
}
/*int Pop(Stack *s, DataType *e)
{
if (NULL == s->top)
{
return FAILURE;
}
Node *p = s->top;
*e = s->top->data;
s->top = p->next;
free(p);
s->length--;
return SUCCESS;
}*/
DataType Pop(Stack *s)
{
DataType e;
if (NULL == s->top)
{
return FAILURE;
}
Node *p = s->top;
e = s->top->data;
s->top = p->next;
free(p);
s->length--;
return e;
}
int ClearStack(Stack *s)
{
if (NULL == s)
{
return FAILURE;
}
Node *p = s->top;
while (p)
{
s->top = p->next;
free(p);
s->length--;
p = s->top;
}
return SUCCESS;
}
int DestroyStack(Stack **s)
{
if (NULL == s)
{
return FAILURE;
}
free(*s);
*s = NULL;
return SUCCESS;
}
头文件
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#define SUCCESS 1000
#define FAILURE 1001
typedef int DataType;
struct node //结点的信息
{
DataType data;
struct node *next;
};
typedef struct node Node;
struct stack //栈的信息
{
Node *top;
int length;
};
typedef struct stack Stack;
int InitStack(Stack **s);
int EmptyStack(Stack *s);
int Push(Stack *s, DataType e);
int LengthStack(Stack *s);
DataType GetTop(Stack *s);
//int Pop(Stack *s, DataType *e);
int Pop(Stack *s);
int ClearStack(Stack *s);
int DestroyStack(Stack **s);
#endif
#include <stdio.h>
#include "LinkStack.h"
int Priority(char ch) //判断运算符优先级
{
switch (ch)
{
case '(':
return 3;
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
int main()
{
Stack *opt_stack, *num_stack;//opt 运算符号,num 运算数字
char str[100] = {0}; //输入的中缀表达式字符串
int i = 0, tmp = 0, j;
if (InitStack(&opt_stack) != SUCCESS || InitStack(&num_stack) != SUCCESS)//将运算符号栈和运算数字栈初始换
{
printf("Init Failure!\n");
}
printf("Please input :\n");
scanf("%s", str); //输入中缀表达式字符串
while (str[i] != '\0' || EmptyStack(opt_stack) != SUCCESS)//当字符串未结束或运算符栈不为空时 进入循环
{
if (str[i] >= '0' && str[i] <= '9') //判断第 i 个数字是否为数字
{
tmp = tmp * 10 + str[i] - '0';
i++;
if (str[i] > '9' || str[i] < '0')
{
Push(num_stack, tmp); //数字结束时将当前数字进栈
tmp = 0;
}
}
else
{
if (EmptyStack(opt_stack) == SUCCESS || (GetTop(opt_stack) == '(' && str[i] != ')')
|| (Priority(str[i]) > Priority(GetTop(opt_stack))))
{
Push(opt_stack, str[i]);
i++;
continue;
}
if (GetTop(opt_stack) == '(' && str[i] == ')')
{
Pop(opt_stack);
i++;
continue;
}
if ((str[i] == '\0' && EmptyStack(opt_stack) != SUCCESS) ||
Priority(str[i]) <= Priority(GetTop(opt_stack)) ||
(str[i] == ')' && GetTop(opt_stack) != '('))
{
switch(Pop(opt_stack))
{
case '+':
Push(num_stack, Pop(num_stack) + Pop(num_stack));
break;
case '-':
j = Pop(num_stack);
Push(num_stack, Pop(num_stack) - j);
break;
case '*':
Push(num_stack, Pop(num_stack) * Pop(num_stack));
break;
case '/':
j = Pop(num_stack);
Push(num_stack, Pop(num_stack) / j);
break;
}
}
}
}
printf("result is %d!\n", Pop(num_stack));
return 0;
}