P1241 括号序列

本文介绍了一个关于平衡括号序列的问题,需要编写代码扫描输入字符串,对每个右括号找到最近的左括号进行配对,未匹配的括号则在其后添加相应符号使其成对。给出了C++代码示例作为解答方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

定义如下规则:

  1. 空串是「平衡括号序列」
  2. 若字符串 S 是「平衡括号序列」,那么[S] 和(S) 也都是「平衡括号序列」
  3. 若字符串 A 和 B 都是「平衡括号序列」,那么 AB(两字符串拼接起来)也是「平衡括号序列」。

例如,下面的字符串都是平衡括号序列:

()[](())([])()[]()[()]

而以下几个则不是:

([])(())([()

现在,给定一个仅由 ()[]构成的字符串 s,请你按照如下的方式给字符串中每个字符配对:

  1. 从左到右扫描整个字符串。
  2. 对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。

配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。

输入格式

输入只有一行一个字符串,表示 s。

输出格式

输出一行一个字符串表示你的答案。

输入输出样例

输入 #1

([()

输出 #1

()[]()

输入 #2

([)

输出 #2

()[]()

说明/提示

数据规模与约定

对于全部的测试点,保证 s 的长度不超过 100,且只含 ()[] 四种字符。

题目难度

普及-

参考思路

原题目:扫描一遍原序列,对每一个右括号,找到在它左边最靠近它的左括号匹配,如果没有就放弃。

翻译:扫描一遍原序列,当找到一个右括号(即找到一个 ' ) ' 或者 ' ] ' 时),以它为起点向左找,找到一个没被标记成功匹配的左括号(即找到一个 ' ( ' 或者 ' [ ' ),如果两者匹配的话,标记它们成功匹配,如果不匹配,或者找不到左括号的话,不做任何标记。

原题目:在以这种方式把原序列匹配完成后,把剩下的未匹配的括号补全。

翻译:上面扫描一遍标记完成功匹配的括号之后,扫描一遍序列,对于标记过的括号,则直接输出;对于没有标记的括号,则补全成对输出

举例:如果有个 ' [ ' 或 ' ] ' 没被标记匹配,则输出 [ ]

例:

输入:

( [ ) ] )

输出:

( [ ( ) ] )

参考代码

#include <bits/stdc++.h>

using namespace std;

int a[105]; // 标记

int main()
{
    int i,j;
    string s;
    cin >> s;
    for (i=0; i<s.length(); i++) {
        if (s[i] == ')') { // 找到了右括号
            for (j=i-1; j>=0; j--) {
                if (s[j] == '(' and a[j] == 0) { // 找到了没被匹配过的左括号且匹配成功
                    a[i] = a[j] = 1;
                    break;
                }
                else if (s[j] == '[' and a[j] == 0) break; // 找到了左括号但匹配失败
            }
            // 找不到左括号,不做任何操作
        }
        // 下面同理
        else if (s[i] == ']') {
            for (j=i-1; j>=0; j--) {
                if (s[j] == '[' and a[j] == 0) {
                    a[i] = a[j] = 1;
                    break;
                }
                else if (s[j] == '(' and a[j] == 0) break;
            }
        }
    }
    for (i=0; i<s.length(); i++) {
        if (a[i] == 0) { // 没有匹配则成对输出
            if (s[i] == '(' or s[i] == ')') cout << "()";
            else cout << "[]";
        }
        else cout << s[i]; // 匹配成功则直接输出
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值