1. 程式人生 > >封裝棧的基本操作及棧的應用

封裝棧的基本操作及棧的應用


封裝棧的基本操作及棧的應用

用棧解決括號的匹配問題

用棧解決RPN(逆波蘭表示式–字尾表示式)求值


程式程式碼如下:


Stack.h


typedef int SDataType;
//typedef char SDataType;

#define MAXSIZE 10 

typedef struct Stack
{
	SDataType _array[MAXSIZE];
	int _top; // 標記棧頂(棧中元素的個數) 
}Stack;

void StackInit(Stack* ps);
void StackPush(Stack* ps,
SDataType data); void StackPop(Stack* ps); SDataType StackTop(Stack* ps); int StackSize(Stack* ps); int StackEmpty(Stack* ps);

Stack.c

#include "stack.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>

//初始化
void StackInit(Stack* ps)
{
	assert(ps);
	ps->_top =
0; } //壓棧 void StackPush(Stack* ps, SDataType data) { assert(ps); if (MAXSIZE - 1 == ps->_top) { printf("棧已滿\n"); return; } ps->_array[ps->_top++] = data; } //出棧 void StackPop(Stack* ps) { assert(ps); if (1 == StackEmpty(ps)) return; ps->_top--; } //獲取棧頂元素 SDataType StackTop(Stack*
ps) { assert(ps); return ps->_array[ps->_top-1]; } //求棧大小 int StackSize(Stack* ps) { assert(ps); return ps->_top; } //判斷棧是否為空 int StackEmpty(Stack* ps) { assert(ps); return 0 == ps->_top; }

test.c


#include "stack.h"
#include <stdio.h>
#include <stdlib.h>

//1. 封裝棧的基本操作
// 建議:靜態
#if 0
void TestStack()
{
	Stack s;
	StackInit(&s);
	StackPush(&s, 1);
	StackPush(&s, 2);
	StackPush(&s, 3);
	StackPush(&s, 4);
	printf("size = %d\n", StackSize(&s));
	printf("top = %d\n", StackTop(&s));
	if (1 == StackEmpty(&s))
		printf("棧為空\n");
	StackPop(&s);
	StackPop(&s);
	printf("size = %d\n", StackSize(&s));
	printf("top = %d\n", StackTop(&s));
	StackPop(&s);
	StackPop(&s);
	printf("size = %d\n", StackSize(&s));
	if (1 == StackEmpty(&s))
		printf("棧為空\n");

}

int main()
{
	TestStack();
	system("pause");
	return 0;
}
#endif

//2. 棧的應用
#if 0
//用棧解決括號的匹配問題
int IsBrackets(char c)
{
	if (('(' == c || ')' == c) || ('[' == c || ']' == c) || ('{' == c || '}' == c))
		return 1;
	return 0;

}

void MatchBrackets(const char* str)
{
	int i = 0;
	int size = 0;
	Stack s;
	if (NULL == str)
		return;
	StackInit(&s);
	size = strlen(str);
	for (i = 0; i < size; ++i)
	{
		if (IsBrackets(str[i]))
		{
			//當前字元為左括號
			if ('(' == str[i] || '[' == str[i] || '{' == str[i])
			{
				StackPush(&s, str[i]);
			}
			//當前字元為右括號
			else
			{
				char c;
				if (StackEmpty(&s))
				{
					printf("右括號多於左括號!\n");
					return;
				}
				//檢測當前括號是否與棧頂括號匹配
				c = StackTop(&s);
				if (('(' == c && ')' == str[i]) || 
					('[' == c && ']' == str[i]) || 
					('{' == c && '}' == str[i]) )
				{
					StackPop(&s);
				}
				else
				{
					printf("左右括號次序不匹配!\n");
					return;
				}

			}
		}
	}

	if (StackEmpty(&s))
	{
		printf("左右括號次序匹配:)\n");
		return;
	}
	else
	{
		printf("左括號多於右括號!\n");
		return;
	}

}
int main()
{
	char a[] = "(())abc{[(])}";//左右括號次序不匹配
	char b[] = "(()))abc{[]}";//右括號多於左括號
	char c[] = "(()()abc{[]}";//左括號多於右括號
	char d[] = "(())abc{[]()}";//左右括號次序匹配

	MatchBrackets(a);	
	MatchBrackets(b); 
	MatchBrackets(c);
	MatchBrackets(d);

	system("pause");
	return 0;
}
#endif 

#if 1
//用棧解決RPN(逆波蘭表示式--字尾表示式)求值

typedef enum{ADD,SUB,MUL,DIV,DATA}OPERATOR;

typedef struct Cell
{
	OPERATOR _op;
	int data;
}Cell;

//12*(3+4)-6+8/2--->12 3 4 + * 6 - 8 2 / +
int CalcRPN(Cell* RPN, int size)
{
	int i = 0;
	Stack s;
	StackInit(&s);
	for (i = 0; i < size; ++i)
	{
		if (DATA == RPN[i]._op)
			StackPush(&s, RPN[i].data);
		else
		{
			int left = 0, right = 0;
			right = StackTop(&s);
			StackPop(&s);
			left = StackTop(&s);
			StackPop(&s);

			switch(RPN[i]._op)
			{
			case ADD:
				StackPush(&s,left + right);
				break;
			case SUB:
				StackPush(&s, left - right);
				break;
			case MUL:
				StackPush(&s, left * right);
				break;
			case DIV:
				if (0 == right)
				{
					printf("除數為0非法!\n");
					return 0;
				}
				StackPush(&s, left / right);
				break;
			}
		}
	}
	return StackTop(&s);
}

int main()
{
	Cell RPN[] = {{DATA, 12}, {DATA, 3}, {DATA, 4}, {ADD, 0}, {MUL, 0}, {DATA, 6}, 
	             {SUB, 0}, {DATA, 8}, {DATA, 2}, {DIV, 0}, {ADD, 0}};
	printf("%d\n", CalcRPN(RPN, sizeof(RPN) / sizeof(RPN[0])));
	system("pause");
	return 0;
}
#endif

程式執行結果如下:


棧的封裝:
在這裡插入圖片描述

用棧解決括號的匹配問題
在這裡插入圖片描述

用棧解決RPN(逆波蘭表示式–字尾表示式)求值
在這裡插入圖片描述