zoukankan      html  css  js  c++  java
  • 习题3.8 符号配对 (20 分)

    请编写程序检查C语言源程序中下列符号是否配对:/**/()[]{}

    输入格式:

    输入为一个C语言源程序。当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。

    输出格式:

    首先,如果所有符号配对正确,则在第一行中输出YES,否则输出NO。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号;如果缺少右符号,则输出左符号-?

    输入样例1:

    void test()
    {
        int i, A[10];
        for (i=0; i<10; i++) /*/
            A[i] = i;
    }
    .
    

    输出样例1:

    NO
    /*-?
    

    输入样例2:

    void test()
    {
        int i, A[10];
        for (i=0; i<10; i++) /**/
            A[i] = i;
    }]
    .
    

    输出样例2:

    NO
    ?-]
    

    输入样例3:

    void test()
    {
        int i
        double A[10];
        for (i=0; i<10; i++) /**/
            A[i] = 0.1*i;
    }
    .
    

    输出样例3:

    YES
    

    括号的匹配,当然首先想起和堆栈有关,题目不难,但是考验写代码的能力。放出我的撇脚代码:

    #include <stdio.h>
    
    /* K & R Stack */
    #define MAXVAL 100
    static int val[MAXVAL];
    static int sp = 0;
    
    void push(int ch)
    {
        if (sp < MAXVAL) {
            val[sp++] = ch;
        } else {
            // stack full
        }
    }
    
    int pop(void)
    {
        if (sp > 0) {
            return val[--sp];
        } else {
            return -1;
        }
    }
    
    int isEmpty(void) { return sp == 0; }
    
    int isLeftSymbol(int ch);
    int getMatcher(int ch);
    const char* getOriginalSymbol(int ch);
    
    int main()
    {
        char symbols[100];
        char line[1000];
        char result[100] = "YES
    ";
        int i, index, ch;
        index = 0;
    
        // 读所有的要配对的符号
        while (fgets(line, sizeof(line)/sizeof(line[0]), stdin) != NULL) {
            if (line[0] == '.' && line[1] == '
    ') {
                break;
            }
            for (i = 0; line[i] != ''; i++) {
                ch = line[i];
                if (line[i] == '/' && line[i+1] == '*') {
                    symbols[index++] = '<';
                    i++;
                } else if (line[i] == '*' && line[i+1] == '/') {
                    symbols[index++] = '>';
                    i++;
                } else if (ch == '(' || ch == ')' ||
                           ch == '[' || ch == ']' ||
                           ch == '{' || ch == '}')
                {
                    symbols[index++] = ch;
                }
            }
        }
        symbols[index] = '';
        
        // printf("%s
    ", symbols);    /* 输出所有读到的符号 */
    
        /* 检查符号匹配 */
        for (i = 0; i < index; i++) {
            int ch = symbols[i];
            if (isLeftSymbol(ch)) { /* 是左边的符号,push 到堆栈里面去 */
                push(symbols[i]);
            } else {    /* 是右边的符号 */
                int leftSymbol = pop(); /* 从堆栈取出要匹配的左边的符号 */
                if (leftSymbol != -1) { /* 还有左边的符号 */
                    int rightSymbol = getMatcher(leftSymbol);
                    if (rightSymbol != ch) {    /* 左边符号想要的右符号是不是现在遇到的右边的符号(ch) */
                        sprintf(result, "NO
    %s-?
    ", getOriginalSymbol(leftSymbol));
                        break;
                    }
                } else {    /* 当前遇到的符号没有左符号来匹配 */
                    sprintf(result, "NO
    ?-%s
    ", getOriginalSymbol(ch));
                    break;
                }
            }
        }
    
        if (i == index && !isEmpty()) {    /* 匹配完所有的括号后,如果堆栈不为空有多余的左括号/符号 */
            sprintf(result, "NO
    %s-?
    ", getOriginalSymbol(pop()));
        }
    
        printf("%s", result);
        return 0;
    }
    
    
    int isLeftSymbol(int ch)
    {
        return ch == '<' || ch == '(' || ch == '[' || ch == '{';
    }
    
    int getMatcher(int ch)
    {
        static int map[128] = {
            ['<'] = '>', 
            ['>'] = '<',
            ['('] = ')',
            [')'] = '(',
            ['['] = ']',
            [']'] = '[',
            ['{'] = '}',
            ['}'] = '{'
        };
    
        return ch >= 0 && ch < 128 ? map[ch] : 0;
    }
    
    const char* getOriginalSymbol(int ch)
    {
        static const char *symbols[128] = {
            ['<'] = "/*",
            ['>'] = "*/",
            ['('] = "(",
            [')'] = ")",
            ['['] = "[",
            [']'] = "]",
            ['{'] = "{",
            ['}'] = "}",
        };
    
        return ch >= 0 && ch < 128 ? symbols[ch] : "";
    }
    
    
  • 相关阅读:
    开通第一天,以此随笔作为纪念
    Apache 基于IP访问网站
    命令解释
    vi总结
    RAID
    Windows虚拟机安装
    CentOS虚拟机安装
    通过挂载系统光盘搭建本地yum仓库的方法
    VMware workstation 的安装
    Linux下关于vi命令的详细解说
  • 原文地址:https://www.cnblogs.com/fnmain/p/14585316.html
Copyright © 2011-2022 走看看