• Party解题报告


    Party解题报告

    题目大意

    给定若干个含有()[]和小写英文字母的字符串,问字符串是否是括号配对的。

    题意

    题目描述中使用了递归定义法,考虑到大家还没有学习递归,在此简单解释:

    1. 只含有英文字母的串S是正确的

      这一条可以称为递归的“基本情况”,描述了最“基本”的串。

    2. 如果A, B是正确的,那么AB也是正确的。

      第二条描述了两个正确的串连接后还是正确的。

    3. 如果A是正确的,那么(A)和[B]都是正确的。

      第三条描述了正确的字符串可以被一对配对的括号包括,仍是正确的。

    4. (在题目中没有写出这一条,但根据上下文是显然的) 其他串都不是正确的。

      这一条称为“闭包条款”,严格的表述应该为:正确的字符串集合 C 是所有符合以上三条性质所生成的集合的交集。这条性质最小化了生成的集合。

    通俗地说,这种递归定义严格化了“括号配对”的概念。同时也方便我们进行证明。

    30分做法

    考虑到对于30%的数据,仅出现一种括号,不难证明,仅有一种括号时,括号配对当且仅当左右括号数目相同。只需简单枚举即可得出结果。

    递归分析法

    这种思路即是直接使用定义进行判断,鉴于大家还没有学习递归,在此略去。有兴趣的同学可以查阅关于“语义分析”的递归下降分析法的资料。

    100分做法:栈

    首先仍然考虑只有一种括号的情景。为了方便处理,删去所有英文字符。考虑这样一种方法:

    • 存在一个桶,对于任何字符串S,将S的第一个字符装入桶的顶端,并删去字符串中第一个字符;
    • 对于桶顶第一个元素a和第二个元素b,如果b为左括号、a为右括号且ab配对,则从桶中删除这两个括号。
    • 重复操作直到字符串为空。

    这种思路有些诡异,如果难以理解,可以尝试使用下面的思路证明:

    定理:仅存在一种括号时,最后桶为空当且仅当字符串是正确的。

    部分证明:(可以略去)
    1. 先证 “”。

    • 如果原字符串为空这显然正确。
    • 对字符串S的长度进行数学归纳。如果原串不空,则设原串长为 |S|。归纳假设 0|S|<|S|,S。由于 |S|>0,且串的长度减少能且仅能通过成对地删除括号完成,因而删除的括号必然是成对的。考虑最后一对删除的括号,由于算法流程,删去括号当且仅当他们相邻,所以原串中在他们之间的元素根据此算法变为了空,由于归纳假设,他们之间的串是正确的;再根据定义3,这个括号以及其间的字符串是正确的。由于是“最后一对删除的括号”,这个括号和之间的字符串(称为P)不被S种任何括号包含,因而字符串S可以看成P和另一个使桶为空的字符串A连接而成(AB=ϕ),由于 |A|<|S|,根据归纳假设,A正确。由于A,P正确,根据定义2,S=AP正确。根据归纳原理,原命题得证。

    必要性证明留做练习。

    用同样的方法不难证明,对于两种括号乃至n种括号,这样的方法总是正确的。 证明留作练习。

    这种处理问题的“桶”称为栈,将在以后的学习中详细介绍这种结构。

    标程

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    char str[300];
    char stk[300];
    int m;
    
    int main()
    {
        freopen("party.in", "r", stdin);
        freopen("party.out", "w", stdout);
        scanf("%d
    ", &m);
        for (int i = 1; i <= m; i++) {
            gets(str); int top = 0, j, len;
            for (top = 0, j = 0, len = strlen(str); j < len; j++) {
                switch(str[j]) {
                    case '(': stk[++top] = str[j]; break;
                    case ')': if (stk[top] == '(') top--; else stk[++top] = str[j]; break;
                    case '[': stk[++top] = str[j]; break;
                    case ']': if (stk[top] == '[') top--; else stk[++top] = str[j]; break;
                }
            }
            if (top == 0) puts("Exciting");
            else puts("Everything must follow the BASIC LAW");
        }
        return 0;
    }
  • 相关阅读:
    【12】python模块:itsdangerous(生成临时身份令牌)
    python作业/练习/实战:下载QQ群所有人的头像
    【4】Python操作redis
    【7】Python网络请求:requests模块
    【6】Python网络请求:urllib模块
    python学习笔记:目录结构
    【9】Python接口开发:flask Demo实例
    【8】Python接口开发:PythonWEB框架之Flask
    前端学习笔记——引入css文件、样式优先级
    Yii2模型介绍
  • 原文地址:https://www.cnblogs.com/ljt12138/p/6684353.html
Copyright © 2020-2023  润新知