###definition.h
#pragma once
#include
#include
#include
#define len 10
#define Stack_size 20
typedef enum comput //运算
{
OP_NUM=1,//操作数
OP_SYMBOL=2,//操作符:加减乘除
OP_ADD=3,
OP_SUB=4,
OP_MUL=6,
OP_DIV=7,
}comput;
typedef struct Cell //顺序表内,栈内存储的元素(有两个成员)
{
comput _type;//类型:操作数/操作符
int value; // 数值/(add/sub/mul/div)
}Cell;
typedef Cell DataType;
typedef struct Stack
{
DataType* _array;//数组指针
size_t _top; //栈顶
size_t _end;//最大容量
}Stack;
typedef struct SeqList
{
DataType *a;
size_t size;
size_t capacity;
}SeqList;
###test.c
#include"functions.h"
// 思路:
//1.用户输入前缀表达式,将式存入顺序表A
//2.将前缀表达式转化为后缀表达式,并存入顺序表B中
//3.对B内后缀表达式运算(借助一个栈临时存储操作符),并输入结果
void test()
{
SeqList list, list1;
Stack s;
SeqInit(&list);
SeqInit(&list1);
StackInit(&s);
SeqPushBack(&list, OP_NUM, 3);
SeqPushBack(&list, OP_SYMBOL, OP_MUL);
SeqPushBack(&list, OP_NUM, 4);
SeqPushBack(&list, OP_SYMBOL, OP_ADD);
SeqPushBack(&list, OP_NUM, 2);
//34*2+
turn_reverse_polish_expression(&list, &list1, &s);//前缀表达式转后缀表达式
for (size_t i = 0;i < list1.size;i++)
{
printf("%2d", list1.a[i]._type);
printf("%2d\n", list1.a[i].value);
}
int i= comput_reverse_polish_expression(&list1,&s);//计算后缀表达式
printf("结果为%d\n", i);
}
int main()
{
test();
system("pause");
return 0;
}
###seqlist.h
#pragma once
#include"definition.h"
void SeqInit(SeqList* pSeq)
{
//初始化顺序表:分配内存,将已用长度置零,全长为len
assert(pSeq);
pSeq->a = (DataType*)malloc(sizeof(DataType)*len);
pSeq->size = 0;
pSeq->capacity = len;
}
void Seqcheckfull(SeqList **pSeq)
{
//检查顺序表是否满
if ((*pSeq)->size == (*pSeq)->capacity)
{
(*pSeq)->a = (DataType*)realloc((*pSeq)->a, sizeof(DataType)*len * 2);
(*pSeq)->capacity *= 2;
}
}
void SeqPushBack(SeqList* pSeq, comput _type, int value)
{
//判断是否满,满则用realloc多分配一倍内存。未满将数据存在最后,size++
assert(pSeq);
Seqcheckfull(&pSeq);
pSeq->a[pSeq->size]._type = _type;
pSeq->a[pSeq->size].value = value;
pSeq->size++;
}
void SeqDestory(SeqList* pSeq)
{
//销毁顺序表:free掉头数据区头指针,置为空,在把已用长度和总长置零
assert(pSeq);
free(pSeq->a);
pSeq->a = NULL;
pSeq->capacity = 0;
pSeq->size = 0;
}
void SeqPopBack(SeqList* pSeq)
{
//判断顺序表是否为空,空则报错返回,未空则size--
assert(pSeq);
if (pSeq->size == 0)
{
printf("SeqList is empty!");
assert(0);
}
pSeq->size--;
}
###stack1.h
#pragma once
#include"definition.h"
// 栈的实现接口
void StackInit(Stack* s)//栈的初始化
{
assert(s);
s->_array = (DataType*)malloc(sizeof(DataType)*Stack_size);
s->_end = Stack_size;
s->_top = 0;
}
void StackPush(Stack* s, comput _type,int value)//入栈
{
assert(s);
if (s->_end == s->_top)//栈已满
{
s->_end *= 2;
s->_array = (DataType*)realloc(s->_array, sizeof(DataType)*(s->_end));
}
s->_array[s->_top]._type = _type;
s->_array[s->_top].value = value;
(s->_top)++;
}
void StackPop(Stack* s)//出栈
{
assert(s);
if (s->_top == 0)
{
printf("the stack is empty");
}
else
{
s->_top--;
}
}
DataType StackTop(Stack* s)//取栈顶元素
{
assert(s);
if (s->_top == 0)
{
assert(0);
}
int num = s->_top;
DataType i = s->_array[(--num)];
return i;
}
int StackEmpty(Stack* s)//判断栈是否为空
{
if (s->_top == 0)
{
return 1;
}
else
{
return 0;
}
}
###functions.h
#pragma once
#include"stack1.h"
#include"seqlist.h"
void turn_reverse_polish_expression(SeqList *list, SeqList *list1, Stack *s)
{
//1.从list开始读,遇到操作数就存入list1.栈为空时遇到操作符就入栈
//当再次遇到操作符时,仅有该操作符优先级>栈顶操作符优先级时,才入栈,否则,将顺序表内倒数2个
//取出,倒2作左值,倒一作右值,运算过后再将新数存入顺序表,将当前操作符存入s
//直至list1长度与list相等
assert(list);
assert(list1);
assert(s);
DataType *cur = list->a;
size_t size = list->size;
while (size)
{
if (cur->_type == OP_NUM)//遇到操作数
{
SeqPushBack(list1, cur->_type, cur->value);
}
if (cur->_type == OP_SYMBOL)//遇到操作符
{
if (StackEmpty(s) == 1 || cur->value - StackTop(s).value>=2)//当前操作符的优先级比栈顶操作符优先级高||栈为空
{
StackPush(s, cur->_type, cur->value);
}
else
{
while (StackEmpty(s)==0 && (cur->value- StackTop(s).value<2))
{
SeqPushBack(list1, StackTop(s)._type, StackTop(s).value);
StackPop(s);
}
StackPush(s, cur->_type, cur->value);
}
}
size--;
cur++;
}
if (StackEmpty(s) == 0)//如果顺序表list已经走到尾,则应该判断栈s是否为空,如果不为空则补在list1后面。
{
while (StackEmpty(s) != 1)
{
SeqPushBack(list1, StackTop(s)._type, StackTop(s).value);
StackPop(s);
}
}
}
int comput_reverse_polish_expression(SeqList *list1, Stack *s)
{
assert(list1);
assert(s);
DataType *cur = list1->a;
size_t size = list1->size;
while (size) // 34*2+
{
if (cur->_type == OP_NUM)
{
StackPush(s, cur->_type, cur->value);
size--;
cur++;
}
if (cur->_type == OP_SYMBOL)
{
int newnum = 0;
int right = StackTop(s).value;
StackPop(s);
int left = StackTop(s).value;
StackPop(s);
switch (cur->value)
{
case OP_ADD:
{
newnum = left + right;
break;
}
case OP_SUB:
{
newnum = left - right;
break;
}
case OP_MUL:
{
newnum = left*right;
break;
}
case OP_DIV:
{
newnum = left / right;
break;
}
default:
break;
}
StackPush(s, cur->_type, newnum);
size--;
cur++;
}
}
return StackTop(s).value;
}