栈的简单应用——括号匹配问题和逆波兰表达式

本文探讨了括号匹配算法,通过使用栈结构判断括号是否正确配对,以及逆波兰表达式的实现原理,包括如何将普通数学表达式转换为后缀表达式,并利用栈进行求值。

括号匹配问题
问题:假设一个算法表达式种包含圆括号、方括号、花括号三种类型的括号,编写一个函数,用来判断表达式种的括号是否正确配对。

括号匹配有四种情况:
(1)右括号多于左括号
(2)左右括号次序匹配不正确
(3)左括号多于右括号
(4)左右括号匹配正确

实现思想 :定义一个栈,遇到左括号时就入栈,遇到右括号时便令栈顶店的左右括号进行匹配
当栈为空,右括号多于左括号
当字符串遍历结束时,栈不为空,左括号多于右括号
当栈顶的左括号和右括号不匹配时,次序不匹配
当字符串遍历结束后,栈为空,匹配正确

#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>
stack<char> s;
bool IsBrackets(char e)//判断字符是否为空
{
	if (e == '(' || e == ')' || e == '[' || e == ']' || e == '{' || e == '}')
		return true;
	return false;
}
bool MatchBrackets(char * pStr)
{
	assert(pStr);
	int len = strlen(pStr);
	for (int i = 0; i < len; i++)
	{
		if (!IsBrackets(pStr[i]))//不是括号
			continue;
		else
		{
			if (pStr[i] == '(' || pStr[i] == '[' || pStr[i] == '{')//左括号入栈
				s.push(pStr[i]);
			else//右括号
			{
				if (s.empty())//栈顶为空
				{
					cout << "右括号多于左括号" << endl;
					return false;
				}
				char c = s.top();
				if (c == '(' && c == ')' || c == '[' && c == ']' || c == '{' && c == '}')
					s.pop();
				else
				{
					cout << "右左括号次序匹配不正确" << endl;
					return false;
				}
			}
		}
	}
	if (!s.empty())
	{
		cout << "左括号多于右括号" << endl;
		return false;
	}
	cout << "左右括号匹配正确" << endl;
	return true;
}
int main()
{
	char str[100];
	cin >> str;
	MatchBrackets(str);
	system("pause");
	return 0;
}

逆波兰表达式
逆波兰表达式也叫后缀表达式,先操作数,后操作符。
实现原理:栈后进先出 ,顺序遍历波兰表达式,遇到操作数的时候入栈 , 遇到操作符,先让操作数出栈运算操作数,然后再把运算结果入栈,所有的算式都可以用逆波兰表达式写出来

#ifndef __REVERSE_ORDER_EXPRESSION_H__
    //12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +
    //给定数列操作12 3 4 + *6 - 8 2/ +
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAXSIZE 15
typedef enum Operation
{
    ADD,
    SUB,
    MUL,
    DIV,
    DATA
}Way;
typedef int DataType;
typedef struct Cell
{
    Way way;
    DataType data;
}Cell;
//进行逆波兰填栈操作
//创建栈
typedef struct Stack
{
    DataType data[MAXSIZE];
    int top;
}Stack;
//栈的初始化
void InitStack(Stack * s)
{
    s->top = 0;
}
//入栈
void PushStack(Stack * s, DataType d)
{
    assert(s);
    if (s->top == MAXSIZE)
    {
        printf("栈已满,无法入\n");
        return;
    }
    s->data[s->top] = d;
    s->top++;

}
//取栈顶元素并出栈
DataType TopStack(Stack *s)
{
    assert(s);
    if (s->top == 0)
    {
        printf("没有元素,无法取栈顶\n");
        return ;
    }
    s->top--;
    return s->data[s->top];
}
DataType order(Cell arr[],int size,Stack *s)
{
    int i = 0;
    int a = 0, b = 0;
    for (i = 0; i<size;i++)
    {
        a = 0;
        b = 0;
        switch(arr[i].way)
        {
        case ADD:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b + a);
                    break; 
        }
        case SUB:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b - a);
                    break; 
        }
        case MUL:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b * a);
                    break; 
        }
        case DIV:
        {
                    a = TopStack(s);
                    b = TopStack(s);
                    PushStack(s, b / a);
                    break;
        }
        case DATA:
        {
                     PushStack(s, arr[i].data );
                    break;
        }
        default:
        {
                   printf("给定值错误,请重新给值n");
                    break;
        }
        }
    }
    return TopStack(s);
}
int main()
{
    Stack s;
    Cell arr[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 },
    { ADD, 0 }, { MUL, 0 }, { DATA, 6 }, { SUB, 0 }, {DATA,8}, {DATA,2}, {DIV,0}, {ADD,0} };
    int size = sizeof(arr) / sizeof(arr[0]);
    InitStack(&s);
    printf("该表达式12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +的值为%d \n", order(arr, size, &s));
    system("pause");
    return 0;
}

#endif 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值