括号匹配_逆波兰函数(栈)

1.括号匹配

  • 取一个字符:

  • 1.检测该字符是否为括号:
    是括号,继续1,否则返回

  • 2.如果是左括号–>入栈
  • 3.如果是右括号,检测该括号是否与栈顶括号匹配
    是:将栈顶元素出栈
    否:括号的匹配次序出错

  • 栈是否为空:
    空:正确
    非空:左比右括号多

int IsBrackets(char ch)//判断括号函数
{
    if (('(' == ch) || (')' == ch)
        || ('[' == ch) || (']' == ch)
        || ('{' == ch) || ('}' == ch))
    {
        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 < size; i++)
    {
        if (IsBrackets(str[i]))
        {   
            //当前字符为左括号
            if ('(' == str[i] || '[' == str[i] || '{' == str[i])
                StackPush(&s, str[i]);
            else//当前为右括号
            {   
                char ch;
                if (StackEmpty(&s))//判断栈顶元素是否为空
                {
                    printf("右括号比左括号多!!!\n");
                    return;
                }
                ch = StackTop(&s);
                if (!(('(' == ch && ')' == str[i])
                    || ('[' == ch && ']' == str[i])
                    || ('{' == ch && '}' == str[i])))//检测当前括号是否与栈顶括号匹配
                {
                    printf("左右括号次序匹配出错!!!\n");
                    return;
                }
                StackPop(&s);
            }
        }
    }
    if (StackEmpty(&s))
        printf("括号匹配正确!\n");
    else
        printf("左括号比右括号多!!!\n");
}

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

程序输出结果:
这里写图片描述


2.逆波兰函数

//12 3 4 + * 6 - 8 2 / +

//枚举
enum {ADD, SUB, MUL, DIV, DATA};

//定义一个结构体分别存放符号和数据
typedef struct RPN
{
    int opera;
    int data;
}RPN;

int _RPN(RPN *p, int size)
{
    int left, right;
    Stack s;
    StackInit(&s);

    while (size--)
    {
        if (DATA == p->opera)//若数组第一个元素为数据,则进行压栈,以此类型
        {
            StackPush(&s, p->data);
        }
        else//为其他则说明是符号,将栈中元素出栈,先出的为右操作数
        {
            right = StackTop(&s);
            StackPop(&s);

            left = StackTop(&s);
            StackPop(&s);

            switch (p->opera)
            {
            case ADD:
                StackPush(&s, left + right);
                break;
            case SUB:
                StackPush(&s, left - right);
                break;
            case MUL:
                StackPush(&s, left * right);
                break;
            case DIV:
                StackPush(&s, left / right);
                break;
            }
        }
        p++;
    }
    return StackTop(&s);
}

int main()
{
    //创建一个数组放逆波兰表达式
    RPN p[] = { { 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(p) / sizeof(p[0]);
    printf("%d\n", _RPN(p, size));
    system("pause");
    return 0;
}

程序输出结果为:82


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值