请编写程序检查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
代码+总结:
换种方式来写吧
首先这种括号配对问题肯定先想到栈。这里为了方便,我把 ([{ /* 统称为左括号,另一边统称为右括号。
输入的是一个以 单行. 为结尾的c语言代码,而我们要的只是符号,所以能想到我们先用循环把代码逐部分读入,当读到以 . 为首元素的部分时退出循环。
再这个大循环内我们还要对读入的部分再做循环,来找到我们需要的括号类字符处理。其中比较特殊的时 /* */ 两个,我们再读取的时候对这两个字符做特殊处理,用 值 1,2分别代表这两个字符,再把读取到的有效字符进行处理,这里我把读取到的字符用函数judge()处理:
char str[1000]; scanf("%s", str); // 先输入下字符数组
while (str[0] != '.')
{
for (int i = 0; str[i]; i++)
{
// 下面一堆if其实就是查找是不是括号啥的
if (str[i] == '/' && str[i+1] == '*') {i ++; flag = judge(1);}
else if (str[i] == '*' && str[i+1] == '/') {i ++; flag = judge(2);}
else if (str[i] == '(' || str[i] == ')') flag = judge(str[i]);
else if (str[i] == '[' || str[i] == ']') flag = judge(str[i]);
else if (str[i] == '{' || str[i] == '}') flag = judge(str[i]);
if (flag) return 0; // 如果上面的judge返回1就直接return
}
memset(str, 0, sizeof(str)); // 重置一下暂存的字符数组
scanf("%s", str); // 输入新的字符数组
}
可以看到我还用flag来接收了judge()的返回值,先留着不说,我们来分析judge()要干的活都有啥。
judge()负责处理输入的括号字符,可以说是这段代码的核心函数。那么怎么样才算是不能匹配呢?
接下来介绍一下分辨条件:
如果栈是空的,且读入的是右括号--不匹配,直接输出NO+七七八八的
如果栈非空:
读取到左括号,直接入栈
读取到右括号:
1.如果与栈顶匹配,栈顶退栈。
2.如果不匹配--不匹配,直接输出NO+七七八八的。
最后读取代码结束后,如果栈内非空,说明有左括号没得匹配,直接输出NO+七七八八的。
知道了条件,写judge()就轻松多了,但是想要输出 NO+七七八八的 之后就让程序停止运行,就得有个东西通知主函数我已经输出过 NO+七七八八的 的了,这就是用flag来接收judge()返回值的作用。
int judge(char ch)
{
// 如果栈还是空的
if (top == 0 )
{
to_str(ch);
// 如果读取到的是右侧字符,那么肯定不匹配,直接输出no
if (ch == 2 || ch == ')' || ch == ']' || ch == '}') {printf("NO\n?-%s", note); return 1;}
stack[top++] = ch;
}
else // 栈非空
{
to_str(stack[top - 1]);
if (ch == 1 || ch == '(' || ch == '[' || ch == '{') stack[top++] = ch; // 左括号直接入栈
else // 右括号判断
{
if (ch - stack[top-1] == 1 || ch - stack[top-1] == 2) top--; // 能配对的话退栈
else {printf("NO\n%s-?", note); return 1;} // 不能配对的话结束
}
}
return 0;
}
可以看到我在这里面又弄了个 to_str(),由于之前图方便把 /* */ 作了特殊处理,因此在输出的时候就要把 1、2 翻译成 /* 、*/。
void to_str(char ch)
{
memset(note, 0, sizeof(note));
if (ch == 1) {note[0] = '/'; note[1] = '*';}
else if (ch == 2) {note[0] = '*'; note[1] = '/';}
else note[0] = ch;
}
到这代码就差不多结束了,再在主函数循环后添加一个判断栈是否非空的语句就ok了,不过需要注意一下,如果非空的话我们要输出栈底的元素(题目要求第一个不匹配的)
// 结束循环后如果栈内还有东西的话,那么括号肯定不匹配
if (top != 0)
{
to_str(stack[0]); // stack[0] 栈底
printf("NO\n%s-?", note);
return 0;
}
printf("YES");
接下来给出完整代码
#include<stdio.h>
#include<string.h>
char stack[200], note[3];
int top = 0;
void to_str(char ch) // 因为把 /* */ 当作一个字符处理了,所以在这里要还原一下
{
memset(note, 0, sizeof(note));
if (ch == 1) {note[0] = '/'; note[1] = '*';}
else if (ch == 2) {note[0] = '*'; note[1] = '/';}
else note[0] = ch;
}
int judge(char ch)
{
// 如果栈还是空的
if (top == 0 )
{
to_str(ch);
// 如果读取到的是右侧字符,那么肯定不匹配,直接输出no
if (ch == 2 || ch == ')' || ch == ']' || ch == '}') {printf("NO\n?-%s", note); return 1;}
stack[top++] = ch;
}
else // 栈非空
{
to_str(stack[top - 1]);
if (ch == 1 || ch == '(' || ch == '[' || ch == '{') stack[top++] = ch; // 左括号直接入栈
else // 右括号判断
{
if (ch - stack[top-1] == 1 || ch - stack[top-1] == 2) top--; // 能配对的话退栈
else {printf("NO\n%s-?", note); return 1;} // 不能配对的话结束
}
}
return 0;
}
int main()
{
int flag = 0;
char str[1000]; scanf("%s", str); // 先输入下字符数组
while (str[0] != '.')
{
for (int i = 0; str[i]; i++)
{
// 下面一堆if其实就是查找是不是括号啥的
if (str[i] == '/' && str[i+1] == '*') {i ++; flag = judge(1);}
else if (str[i] == '*' && str[i+1] == '/') {i ++; flag = judge(2);}
else if (str[i] == '(' || str[i] == ')') flag = judge(str[i]);
else if (str[i] == '[' || str[i] == ']') flag = judge(str[i]);
else if (str[i] == '{' || str[i] == '}') flag = judge(str[i]);
if (flag) return 0; // 如果上面的judge返回1就直接return
}
memset(str, 0, sizeof(str)); // 重置一下暂存的字符数组
scanf("%s", str); // 输入新的字符数组
}
// 结束循环后如果栈内还有东西的话,那么括号肯定不匹配
if (top != 0)
{
to_str(stack[0]);
printf("NO\n%s-?", note);
return 0;
}
printf("YES");
return 0;
}