括号匹配_进阶篇 ( 7-2 符号配对 )
Posted luoyang0515
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了括号匹配_进阶篇 ( 7-2 符号配对 )相关的知识,希望对你有一定的参考价值。
括号匹配_进阶篇(/.../)
之前有个简单的括号匹配,令这三对括号进行匹配:( ),[ ],{ }
点击跳转:简单的括号匹配问题
之所以说他们简单,是因为每个括号都只占一个字符。
而进阶篇,虽然说起来很酷,其实就是再多一个对/* */的判断
先上原题
7-2 符号配对 (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
我们可以套用上面简单括号匹配问题的代码,在其基础上修改。
思路还是一样,如果是左括号就入占,如果是右括号就出栈。
由于需要对两个符号都进行判断,只有同时成立才能判断为左括号,所以写出以下接口
//判断字符数组的第i个和第i+1个是不是/*
bool isAsterisk(char a[],int i) {
bool result = false;
if (a[i] == '/'&&a[i + 1] == '*') {
result = true;
}
return result;
}
同理,有判断右括号
//判断字符数组的第i个和第i+1个是不是*/
bool isOtherAsterisk(char a[], int i) {
bool result = false;
if (a[i] == '*'&&a[i + 1] == '/') {
result = true;
}
return result;
}
再将其放入主函数的遍历循环中,通过判断是否为左括号决定入栈
if (isAsterisk(a, i)) { //如果是/*就把两个入栈,同时i额外+1,避免/*/错误
Push(stack, a[i]);
Push(stack, a[i + 1]);
i++;
}
这里要注意i要额外加1。如果确定是左括号那么星号就相当于/的一部分,不需要再对它进行判断。
如果为右括号,就把这个右括号和栈顶进行比较,如果不匹配,就改变result的值。注意要出栈两次。
else if (isOtherAsterisk(a, i)) { //如果是*/就出栈比较
temp = Pop(stack);
if (!(a[i] == temp)) {
result = 0;
break;
}
temp = Pop(stack);
if (!(a[i + 1] == temp)) {
result = 0;
break;
}
}
至此可以对含有特殊括号的语句进行基本的yes和no的判断。
然后是对读入和输出的修改。
首先看读入,不同于之前的一行,这次是一段代码,不仅有空格,还有回车。直到‘.’结束。
看到如此明显的结束条件,自然用循环,但是用什么函数读入呢?不理会回车,因为回车可以用循环来实现,这就变成了逐行读入,直到‘.’。空格是无论如何都避免不了的,所以一想得到要读入空格,不如就试试gets( )函数。
首先根据gets( )函数与我们的结束方式写一个判断是否结束的接口
//判断是否输入结束
bool isEnd(char a[]) {
bool result = false;
//“.回车”输入结束,gets把回车看作 ,而我们逐行读入,于是有以下条件
if (a[0] == '.'&&a[1] == '