BUAA大一下数据结构题解(C程序括号匹配检查)

【问题描述】

编写一程序检查C源程序文件中{}、()等括号是否匹配,并输出第一个检测到的不匹配的括号及所对应括号所在的行号(程序中只有一个括号不匹配)。

注意:

1.除了括号可能不匹配外,输入的C源程序无其它语法错误。

2.字符常量、字符串常量及注释中括号不应被处理,注释包括单行注释//和多行/* */注释

3.字符常量和字符串常量中不包含转义字符\'和\";

4.程序中出现有意义括号的个数不超过200个;

不匹配判断规则:

1.当检测的程序括号为'{'时,若其前序尚未匹配的括号为'('时,输出该'('左括号及所在行号; 

2.当遇到一个不匹配的右括号')'或'}'时,输出该右括号及所在行号;

3.当程序处理完毕时,还存在不匹配的左括号时,输出该左括号及所在行号。

【输入形式】

打开当前目录下文件example.c,查询其括号是否匹配。该文件中每行字符数不超过200。

【输出形式】

若存在括号不匹配时,应输出首先能判断出现不匹配的括号及其所在的行号。当出现括号不匹配时,按下面要求输出相关信息:

without maching <x> at line <n>

其中<x>为‘{’, ‘}’, ‘(’, ‘)’等符号,<n>为该符号所在的行号。

若整个程序括号匹配,则按下面所示顺序输出括号匹配情况,中间没有空格。

(){(()){}}

【样例输入1】

若当前目录下输入文件example.c中内容如下:

#include<stdio.h>

int main(){

printf("{ hello world }\n"); // }

)

【样例输出1】

without maching ')' at line 4

【样例输入2】

若当前目录下输入文件example.c中内容如下:

#include<stdio.h>

int main(){

printf("{ hello world }d\n"); /* }*/

【样例输出2】

without maching '{' at line 2

【样例输入3】

若当前目录下输入文件example.c中内容如下:

#include<stdio.h>

int main(){

printf("{ hello world }d\n"); /* }*/

}

【样例输出3】

(){()}


【样例说明】

样例1:在注释部分和字符串中的括号不考虑,在将程序处理之后得到的括号序列是(){()),遇到右括号时与最近的左括号匹配,发现最后一个小括号和大括号不匹配。

样例2:处理之后的括号序列是(){(),在最后缺少了右大括号,那么应该输出与之相对应的左括号不匹配。

【评分标准】

通过所有测试点得满分。

解题思路:因为题目要求我们判断括号的行数,因此我们要分行来读入,一个一个地判断是否是括号,将所有括号放入数组1中,将‘(’、‘{’放入数组2中,如果读入一个‘)’或‘}’,就在数组2中判断它的前一个括号是否匹配,如果匹配成功,就将匹配到的括号在数组2中删除,如果遇到其他特殊的字符就要特殊对待。

参考代码:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct huohao
{
    char kuo;
    int len;
}allhao[300],skuohao[300];
char shuru[300];
int main()
{
    int i=0,j=0,l=0,k=0,n=0,find=0,x=0,mark=0,y,flag=0;//find表示是否已经找到不匹配的括号
    FILE *in;
    in=fopen("example.c","r");//打开文件
    while(fgets(shuru,201,in)!=NULL&&find==0)//分行读入
    {
        l++;
        n=strlen(shuru);
        for(k=0;k<n;k++)
        {
            if(shuru[k]=='(')
                {
                    allhao[i].kuo=shuru[k];
                    allhao[i].len=l;
                    skuohao[j].kuo=shuru[k];
                    skuohao[j].len=l;
                    i++;
                    j++;
                }//直接存入
            else if(shuru[k]=='{')
                {
                    if(j!=0&&skuohao[j-1].kuo=='(')
                    {
                        printf("without maching '(' at line %d\n",skuohao[j-1].len);
                        find=1;
                        break;
                    }//()内部不能出现{}
                    else
                    {
                        allhao[i].kuo=shuru[k];
                        allhao[i].len=l;
                        skuohao[j].kuo=shuru[k];
                        skuohao[j].len=l;
                        i++;
                        j++;
                    }//直接存入
                }
            else if(shuru[k]==')')
            {
                allhao[i].kuo=shuru[k];
                allhao[i].len=l;
                i++;//首先存入
                if(j==0||skuohao[j-1].kuo!='(')
                {
                    printf("without maching ')' at line %d\n",l);
                    find=1;
                    break;
                }//在skuohao这个数组中进行匹配
                else
                {
                    skuohao[j-1].kuo='\0';
                    skuohao[j-1].len=0;
                    j--;
                }//匹配到就删除
            }
            else if(shuru[k]=='}')
            {
                allhao[i].kuo=shuru[k];
                allhao[i].len=l;
                i++;
                if(j==0||skuohao[j-1].kuo!='{')
                {
                    printf("without maching '}' at line %d\n",l);
                    find=1;
                    break;
                }
                else
                {
                    skuohao[j-1].kuo='\0';
                    skuohao[j-1].len=0;
                    j--;
                }
            }//同上
            else if(shuru[k]=='/'&&shuru[k+1]=='/')
                    break;//读到//
            else if(shuru[k]=='/'&&shuru[k+1]=='*')
            {
                for(x=k+2,mark=0;x<n;x++)
                {
                    if(shuru[x]=='*'&&shuru[x+1]=='/')
                    {
                        mark=1;
                        break;
                    }
                }
                while(mark==0)
                {
                    for(y=0;y<201;y++)
                        shuru[y]='\0';
                    fgets(shuru,201,in);
                    l++;
                    n=strlen(shuru);
                    for(x=0;x<n;x++)
                    {
                        if(shuru[x]=='*'&&shuru[x+1]=='/')
                        {
                            mark=1;
                            break;
                        }
                    }
                }
                k=x+1;
            }//读到/**/的情况
            else if(shuru[k]=='"')
            {
                for(x=k+1;x<n;x++)
                {
                    if(shuru[x]=='\\')
                        x++;
                    else if(shuru[x]=='"')
                        break;
                }
                k=x;
            }//读到“再向后寻找”
            else if(shuru[k]=='\'')
            {
                for(x=k+1;x<n;x++)
                {
                    if(shuru[x]=='\\')
                        x++;
                    else if(shuru[x]=='\'')
                        break;
                }
                k=x;
            }//读到/'
        }
        for(y=0;y<200;y++)
            shuru[y]='\0';//将shuru删除
    }
    if(find==0&&j==0)
    {
        for(j=0;j<i;j++)
            printf("%c",allhao[j].kuo);
    }//如果匹配全部成功,则输出括号
    else if(find==0&&j==1)
        printf("without maching '%c' at line %d\n",skuohao[j-1].kuo,skuohao[j-1].len);//如果最后还上下一个括号没有删除,则输出
    fclose(in);
}

上一篇:windows安装两个不同版本的Java及PATH,CLASSPATH,JAVA_HOME环境变量的解释


下一篇:SpringBoot目录文件结构总结(5)