1. 程式人生 > >資料結構-7-棧的簡單應用--混合運算器

資料結構-7-棧的簡單應用--混合運算器

棧的簡單應用RPN
使用棧動態模擬,混合運算的過程:
38+4*6-25由逆波蘭表示式可得到:
{ OP_NUM, 38 },
{ OP_NUM, 6 },
{ OP_NUM, 4 },
{ OP_SYMBOL, OP_MUL },
{ OP_SYMBOL, OP_ADD },
{ OP_NUM, 25 },
{ OP_SYMBOL, OP_SUB },

//棧的實現
#ifndef stack_h
#define stack_h

#include<stdio.h>
#include<Windows.h>
#include<assert.h>
#include<malloc.h>


typedef int DataType;

typedef struct Stack
{
	DataType* _array;
	size_t _top; //棧頂 
	size_t _end;
}Stack;

// 棧的實現介面 
void StackInit(Stack*s, size_t top);
void StackPush(Stack* s, DataType x);
void StackPop(Stack* s);
DataType StackTop(Stack* s);
size_t StackSize(Stack* s);
int StackEmpty(Stack* s);
void Stackcheck(Stack*s);
void StackPrint(Stack*s);

void StackPrint(Stack*s)
{
	size_t i = 0;
	while (i < s->_top)
	{
		printf("%d ", s->_array[i]);
		i++;
	}
}
void Stackcheck(Stack*s)
{
	if (s->_top >= s->_end)
	{
		DataType*array = (DataType*)realloc(s, sizeof(DataType)* 2);
		assert(array);
		s->_array = array;
		s->_end = s->_end * 2;
	}
}
void StackInit(Stack*s, size_t end)
{
	assert(s&&end > 0);
	s->_array = (DataType*)malloc(end*sizeof(DataType));
	assert(s->_array);

	s->_top = 0;
	s->_end = end;
}

void StackPush(Stack* s, DataType x)
{
	Stackcheck(s);
	s->_array[s->_top] = x;
	s->_top++;
}

void StackPop(Stack* s)
{
	s->_array[s->_top - 1] = 0;
	s->_top--;
}

DataType StackTop(Stack* s)
{
	return s->_array[s->_top - 1];
}

size_t StackSize(Stack* s)
{
	return s->_top;
}

int StackEmpty(Stack* s)
{
	if (s->_top == 0)
		return 1;
	else
		return 0;
}

#endif
//運算器函式實現
#ifndef RPN_h
#define RPN_h

#include"stack.h"

typedef enum RPN_TYPE
{
	OP_NUM,
	OP_SYMBOL,
	OP_ADD,
	OP_SUB,
	OP_MUL,
	OP_DIV,
}RPN_TYPE;

typedef struct Cell
{
	RPN_TYPE _type;//定義每一個操作的單元的型別:數(OP_NUM)還是操作符(OP_SYMBOL)
	int value;//這個操作單元的值
}Cell;

int CountRPN(Cell *rpn, size_t n)//計算函式
{
	assert(rpn);
	Stack s;
	StackInit(&s, 30);
	for (size_t i = 0; i < n; i++)
	{
		if (rpn[i]._type == OP_NUM)
			StackPush(&s, rpn[i].value);//如果是數進行入棧
		else//如果是操作符,取棧頂值作為操作右值,棧頂資料出棧,
		//再取棧頂值作為左值,進行操作後,結果再次入棧,如此最後棧頂只剩最後的結果了
		{
			int right = 0, left = 0;
			right = StackTop(&s);
			StackPop(&s);
			left = StackTop(&s);
			StackPop(&s);
			switch (rpn[i].value)
			{
			case OP_ADD:
				StackPush(&s, left + right);
				break;
			case OP_SUB:
				StackPush(&s, left - right);
				break;
			case OP_MUL:
				StackPush(&s, left * right);
				break;
			case OP_DIV:
				StackPush(&s, left / right);
				break;
			default:
				printf("輸入錯誤!");
				break;
			}
		}
	}
	return StackTop(&s);
}
#endif
//主函式以及測試部分

#include"RPN.h"


void test()
{
	int n = 0;
	Cell rpn[] = {
		{ OP_NUM, 38 },
		{ OP_NUM, 6 },
		{ OP_NUM, 4 },
		{ OP_SYMBOL, OP_MUL },
		{ OP_SYMBOL, OP_ADD },
		{ OP_NUM, 25 },
		{ OP_SYMBOL, OP_SUB },

	};
	n = sizeof(rpn) / sizeof(rpn[0]);
	printf("計算結果:%d\n", CountRPN(rpn, n));

}
int main()
{
	test();
	system("pause");
	return 0;
}