判别算术表达式括号配对

【问题描述】

设计一个算法判别一个算术表达式的圆括号是否正确配对


【输入形式】

一个以@为结尾的算术表达式


【输出形式】

若配对,则输出圆括号的对数;否则输出no


【样例输入】(a+b)/(c+d)@
【样例输出】 2
【样例说明】共有两对括号,输出2
【评分标准】

PS:使用栈相关知识,否则不能得分

思路:

使用堆栈存储左括号。

括号配对的表达式的左右括号对称,根据这一性质,我们可以将左括号压入堆栈,碰到右括号时判断栈顶元素和该右括号是否匹配,匹配成功则将栈顶元素出栈,失败则标志flag为0,直接退出循环。

难点:

我认为这个题的一个难点在于如何将表达式输入。我起初将字符串定义为“char str[MAX] = {0};”使用“cin >> str”输入,后来发现str一旦遇到空格就不会读取后面的表达式,即表达式不完整。cin语句的分隔符为:空格、tab键、换行(回车)。使用gets函数也可以,但可能会用警告,因为gets函数原型为: char *gets(char *str),而我们定义的字符串不是指针型的。

PS:指针字符其实我自己也不太清楚,我在原代码基础上改了一点后,变成运行时错误了。有大佬看到问题的话不妨评论一下告诉小的。(完整的通过代码见最下方!)

#include <iostream>
#include <string>
#include <stack>
#define MAX 100
using namespace std;

/**判断括号是否匹配*/
bool isMatch(char ch1, char ch2)
{
    if((ch1 == '(' && ch2 == ')') || (ch1 == '[' && ch2 == ']') || (ch1 == '{' && ch2 == '}'))
    {
        return true;
    }
    return false;
}

int main()
{
    stack<char> stack1;
    string str; // 定义表达式字符串
    getline(cin, str); // getline函数输入string字符串
    int i = 0, cnt = 0, flag = 1; // i表示字符串下标,cnt为累加器,flag标志是否匹配成功
    while(1)
    {
        // 当扫描到结束符‘@’的时候退出循环
        if(str[i] == '@')
        {
            break;
        }
        // 为左括号时压栈
        if(str[i] == '(' || str[i] == '[' || str[i] == '{')
        {
            stack1.push(str[i]);
        }
        // 为右括号时进行判断
        else if(str[i] == ')' || str[i] == ']' || str[i] == '}')
        {
            // 如果栈为空,表示没有匹配的左括号,匹配失败;如果不匹配,也是匹配失败。flag为0,退出循环
            if(stack1.empty() || !isMatch(stack1.top(), str[i]))
            {
                flag = 0;
                break;
            }
            // 匹配成功,栈顶元素出栈,累加器加一
            stack1.pop();
            cnt++;
        }
        i++;
    }
    // 如果栈为空,表示括号匹配完全且成功,flag为1表示没有多余的括号
    if(stack1.empty() && flag == 1)
    {
        cout << cnt;
    }
    // 匹配失败输出“no”
    else
    {
        cout << "no";
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值