用逆波兰表达式完成简单计算器

###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;
}

你可能感兴趣的:(数据结构)