栈的应用----括号匹配、逆波兰表达式【数据结构】

问题描述:

有一个字符串、判断其中的括号是否匹配?

问题解决:利用栈

1.先将字符串逐次扫描,遇到左括号均入栈,遇到右括号与栈顶字符相比较。

2.若栈为空,则说明字符串中右括号多余

3.若栈不为空,且字符相匹配,栈顶元素出栈,继续检测下一字符,若不匹配,则说明括号匹配的类型不正确

4.若都相匹配且栈为空,则说明字符串中括号匹配正确,若栈不为空,则说明左括号多余。

#include "Stack.h"
#include <string.h>

int IsBracket(char ch)
{
	if ('(' == ch || ')' == ch ||
		'[' == ch || ']' == ch ||
		'{' == ch || '}' == ch)
		return 1;
	return 0;
}
int MatchBracket(const char *pStr)
{
	int i = 0;
	char ch = 0;
	int size = strlen(pStr);
	Stack S;
	InitStack(&S);
	for (; i < size; i++)
	{
		//是括号,处理
		if (IsBracket(pStr[i]))
		{
			//是左括号
			if ('(' == pStr[i] || '[' == pStr[i] || '{' == pStr[i])
			{
				PushStack(&S, pStr[i]);		//入栈
			}
			//是右括号
			else
			{
				//检测栈是不是空
				if (StackEmpty(&S))
				{
					printf(" 右括号比左多!\n");
					return 0;
				}
				else
				{
					ch = TopStack(&S);
					if ('(' == ch && ')' == pStr[i] ||
						'[' == ch && ']' == pStr[i] ||
						'{' == ch && '}' == pStr[i])	//匹配,出栈
					{
						PopStack(&S);
					}
					else						//{{)		//不匹配
					{
						printf("左右括号类型匹配出错!%c %c \n",ch,pStr[i]);
						return 0;
					}
				}
			}
		}
	}
	if (StackEmpty(&S))		//栈为空
	{
		printf("匹配正确!!\n");
		return 1;
	}
	else					//栈不空
	{
		printf("左括号多!!\n");
		return 0;
	}
}

逆波兰表达式求解:

//逆波兰表达式

#include "Stack.h"

typedef enum OPERATOR	//每个元素的状态
{
	ADD,
	SUB,
	MUL,
	DIV,
	DATA
}OPERATOR;

typedef struct Cell		//结构体
{
	OPERATOR _op;
	int data;
}Cell;

int CalcRPN(Cell *RPN, int size)
{
	int i = 0;
	int left = 0;			//左操作数
	int right = 0;			//右操作数
	Stack s;
	InitStack(&s);
	for (; i < size; i++)
	{
		if (RPN[i]._op == DATA)			//是数字,入栈
		{
			PushStack(&s, RPN[i].data);
		}
		else
		{
			right = TopStack(&s);	//右操作数出栈
			PopStack(&s);
			left = TopStack(&s);	//左操作数出栈
			PopStack(&s);
			switch (RPN[i]._op)		//对当前元素的状态进行判断
			{
			case ADD:
				PushStack(&s, left + right);
				break;
			case SUB:
				PushStack(&s, left - right);
				break;
			case MUL:
				PushStack(&s, left * right);
				break;
			case DIV:
				if (0 == right)
				{
					printf("除法有操作数为0!\n");
					return 0;
				}
				PushStack(&s, left / right);
				break;
			default:
				printf("error!\n");
				return 0;
			}
		}
	}
	return TopStack(&s);		//栈中最后的元素即为最终结果
}
void TestRpn()
{
	Cell RPN[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, {ADD, 0},
	{ MUL, 0 }, { DATA, 6 }, { SUB, 0 }, { DATA, 8 }, { DATA, 2 }, 
	{ DIV, 0 }, {ADD, 0} };				//结构体数组(12*(3+4)- 6 + 8/2)

	printf("%d\n", CalcRPN(RPN, sizeof(RPN) / sizeof(RPN[0])));
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值