括号配对问题(I && II)

括号配对问题I

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
3

描述
现在,有一行括号序列,请你检查这行括号是否配对。

输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有”[“,”]”,”(“,”)”四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes
【分析】简单的数据结构–栈或者其它STL工具
代码:
#include <iostream>
#include <stack>
#include <string>
#include <bits/stdc++.h>
using namespace std;

int main()
{
    //freopen("1.txt","r",stdin);
    int n;
    string str;
    cin>>n;
    while (n--)
    {
        cin>>str;
        int len=str.length();
        stack<char> vec;
        for(int i = 0; i < len; i++)
        {
            if(vec.empty()) vec.push(str[i]);
            else if(vec.top()=='[' && str[i]==']') vec.pop();
            else if(vec.top()=='(' && str[i]==')') vec.pop();
            else vec.push(str[i]);
        }
        if(vec.empty()) puts("Yes");
        else puts("No");
    }
    return 0;
}

/*vector 容器的应用*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        vector<char> vec;
        string ch;
        vec.push_back(' ');
        cin>>ch;
        for(int i=0; i<ch.length(); i++){
            vec.push_back(ch[i]); /*vec.back()指代最后一个元素,而vec.end()是访问迭代器 !!*/
            if(vec.back()-1 == *(vec.end()-2) || vec.back()-2 == (int)*(vec.end()-2)){
                vec.pop_back();
                vec.pop_back();
            }
        }
        if(vec.size()==1) puts("Yes");
        else puts("No");
    }
    return 0;
}

/*
3
[(])
(])
([[]()])
No
No
Yes
*/

括号匹配问题II

时间限制:
1000 ms  |  内存限制:
65535 KB 难度:
6

描述
给你一个字符串,里面只包含”(“,”)”,”[“,”]”四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。

如:

[]是匹配的

([])[]是匹配的

((]是不匹配的

([)]是不匹配的

输入
第一行输入一个正整数N,表示测试数据组数(N<=10)

每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100

输出
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入
4
[]
([])[]
((]
([)]
样例输出
0
0
3
2
【分析】:
动态规划的第一种动机是利用递归的重叠子问题,进行记忆化求解,即先用递归法解决问题,再利用重叠子问题转化为动态规划,此题可以用递归来解决:

设序列《括号配对问题(I && II)》最少需要添加DP[i][j]个括号,那么根据不同情况可以用不同的方式来转化子问题

Ø  S形如(S’)或[S’];只需要把S’变成规则的,则S就是规则的了

Ø  S形如(S’:先把S’变成规则的,再在最后加上一个),则S就是规则的。

Ø  S形如[S’或者S’)和上一种情况类似。

Ø  只要序列长度大于1,都可以把S分成两部分:《括号配对问题(I && II)》分别变成规则序列,再合并变成规则序列。

【代码】:

#include <iostream>
#include <stack>
#include <string>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 233;
const int inf = 0x3f3f3f3f;

int n,m,ret,len;
int DP[maxn][maxn];
string str;

int Solve()
{
    for(int i=0; i<len; ++i) DP[i][i-1]=0;
    for(int i=0; i<len; ++i) DP[i][i]=1;
    for(int p=1; p<len; ++p)
    {
        for(int i=0; i<len-p; ++i)
        {
            int j=i+p;
            DP[i][j]=inf;
            if( (str[i]=='(' && str[j]==')') || (str[i]=='[' && str[j]==']'))
                DP[i][j]=min(DP[i][j],DP[i+1][j-1]);
             /*
            if( (str[i]=='(') || (str[i]=='['))
                DP[i][j]=min(DP[i][j],DP[i+1][j])+1;
            if( (str[j]==')') || (str[j]==']'))
                DP[i][j]=min(DP[i][j],DP[i][j-1])+1;
              */
            for(int k=i; k<=j-1; ++k)
                DP[i][j]=min(DP[i][j],DP[i][k]+DP[k+1][j]);
        }
    }
}
int main()
{
    //freopen("1.txt","r",stdin);
    int n;
    scanf("%d",&n);
    while(n--)
    {
        cin>>str;
        len=str.length();
        Solve();
        printf("%d\n",DP[0][len-1]);
    }
    return 0;
}
    原文作者:括号匹配问题
    原文地址: https://blog.csdn.net/u013050857/article/details/51089217
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞