信息学奥赛一本通 1203:扩号匹配问题 | OpenJudge NOI 2.2 2705:扩号匹配问题

【题目链接】

ybt 1203:扩号匹配问题
OpenJudge NOI 2.2 2705:扩号匹配问题

【题目考点】

1. 递归
2. 栈

【解题思路】

解法1:递归

设sign字符数组,各元素初始值都是空格。sign[i]为$表示原字符串第i位置的左括号不匹配,sign[i]为?表示原字符串第i位置的右括号不匹配。将sign末尾添加’\0’,形成一个字符串。
设全局下标si,表示当前遍历到的位置。
遍历字符串:

  • 如果遇到左括号,就调用find()函数。
    find()函数的作用为:使用si遍历字符串,找到第一个右括号。
    • 如果找到左括号,则递归调用find()函数,找与这个左括号配对的右括号。
    • 如果遇到右括号,则结束调用。
    • 如果si遍历到末尾也没有发现右括号,说明这个左括号没法配对。那么在sign数组该左括号出现的位置标记为$。
  • 如果遇到右括号,那么说明该右括号无法配对,在sign数组该右括号出现的位置标记为?。

最后输出字符数组sign

解法2:使用栈

用一个栈保存左括号的下标。
遍历字符串:

  • 如果遇到左括号,则入栈该左括号的下标
  • 如果遇到右括号
    • 如果此时栈为空,说明没有左括号与这个右括号配对,标记这个位置为?
    • 如果栈不空,出栈一个左括号的下标。

遍历结束后,如果栈不空,那么不断出栈直至栈空。每个出栈的数字为一个无法配对的左括号的下标,标记这些位置为$。
输出标记数组。

【题解代码】

解法1:递归
#include <bits/stdc++.h>
using namespace std;
#define N 105
char s[N], sign[N];
int si, len;
void find()//找下一个右括号 如果找到,si指向右括号 如果没找到,做标记 
{
    int lp = si;//当前左括号的下标 
    si++;
    while(si < len)
    {
        if(s[si] == ')')
            return;
        else if(s[si] == '(')
            find();
        si++;
    }
    sign[lp] = '$';//没有找到右括号,左括号的位置标记为$ 
}
int main()
{
	while(cin >> s)
	{
	    len = strlen(s);
		for(int i = 0; i < len; ++i)//初始化sign字符串为空格 
            sign[i] = ' ';
        sign[len] = '\0';
        si = 0;
        while(si < len)
        {
            if(s[si] == ')')//右括号的位置标记为? 
                sign[si] = '?';
            else if(s[si] == '(')
                find();
            si++;
        }
        cout << s << endl << sign << endl;
	}
	return 0;
}
解法2:使用栈
#include <bits/stdc++.h>
using namespace std;
#define N 105
char s[N], sign[N];
int main()
{
	while(cin >> s)
	{
	    stack<int> stk;
        int len = strlen(s);
		for(int i = 0; i < len; ++i)//初始化sign字符串为空格 
            sign[i] = ' ';
        sign[len] = '\0';
        for(int i = 0; i < len; ++i)
        {
            if(s[i] == '(')
                stk.push(i);
            else if(s[i] == ')')
            {
                if(stk.empty())//右括号遇到栈空,该右括号不配对 
                    sign[i] = '?';
                else
                    stk.pop();
            }
        }
        while(stk.empty() == false)//最后栈中剩下的左括号的下标指向的左括号没有配对 
        {
            sign[stk.top()] = '$';
            stk.pop();
        }
        cout << s << endl << sign << endl;
	}
	return 0;
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值