请编写程序检查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<bits/stdc++.h> //此头文件中包含了c++的所有包,包括iostream
using namespace std;
int main() {
string s;
char b[7];
b[1] = '(';
b[2] = ')';
b[3] = '[';
b[4] = ']';
b[5] = '{';
b[6] = '}';//大佬在这个地方用数组先把不是/*和*/ 的单个字符提前存储在数组上,使得后面写起来会少些很多代码
int find = 0;
bool isasimple = false; //这个变量后面用得到,用来描述读入的变量是否与b中的那几个符号相同。
stack<char> bracket; //定义栈类型的变量bracket
while (1) { //这样可以保证除了break以外,该循环可以一直进行。
getline(cin,s); //每次读入一行
if (s==".") goto part2; //如果输入的只有一个.则运行part2部分的代码
for (int i = 0; i < s.length(); i++) { // */是两个字符比较特殊,单独讨论
if (s[i] == '/' && 1 + i < s.length())
if (s[i + 1] == '*') {
bracket.push(s[i]); //我们将两个字符以/的形式保存,这样方便
i++; //因为这时候处理了两个字符所以在for循环本身就要i++的基础上,再进行一次i++
continue; //继续下一次for循环
}
if (s[i] == '*' && 1 + i < s.length())
if (s[i + 1] == '/') {
if (bracket.empty()) {
cout << "NO" << endl << "?-*/" << endl; //如果此时栈为空,说明缺少/*
return 0;
} else {
if (bracket.top() != '/') {
cout << "NO" << endl << bracket.top() << "-?" << endl;
//如果栈顶元素存的不是/说明此时的/可以存在栈顶元素的后面,也可能不存在,
//即/存在与否是不确定的,但可以确定的是栈顶元素没有对应的右符号
return 0;
} else {
bracket.pop(); //如果是/则弹出,继续下一次for循环
i++; //弹栈是弹一个,但是一下子处理了两个字符,所以在for循环本身就要i++的基础上,再进行一次i++
continue;
}
}
}
isasimple = false; //不是s[i]/*或*/ ,则执行下面的程序
for (find = 1; find <= 6; find++) {
if (b[find] == s[i]) {//找一下是不是剩余的六个字符
isasimple = true;
break;
}
}
if (isasimple) {
if (find % 2 == 1) { //存在奇数位置的都是左符号
bracket.push(s[i]); //左符号就得入栈
continue;
} else { //find是偶数,则是右符号
if (bracket.empty()) { //如果栈空,说明这个右符号没有对应的左符号
cout << "NO" << endl << "?-" << b[find] << endl;
return 0;
} else {
if (bracket.top() == '/') { //如果栈顶元素是/,但此时我们要进行比较的是剩下的六个字符,所以只能说明栈顶元素/*没有对应的右符号
cout << "NO" << endl <<"/*-?" << endl;
return 0;
} else if (bracket.top() != b[find - 1]) {
//该语句的执行条件是目前比较的是右符号,栈顶元素不是该右符号对应的左符号,说明栈顶元素缺少其本身对应的右符号
cout << "NO" << endl << bracket.top() << "-?" << endl;
return 0;
} else {//如果栈顶元素是该右符号对应的左符号,则将栈顶元素弹出
bracket.pop();
continue;
}
}
}
}
}
}
part2:
if (bracket.empty()) { //如果栈不是空的,也还会出错。
cout << "YES" << endl;
} else {
cout << "NO" << endl << bracket.top() << "-?" << endl;
//因为读入的符号是.说明输入已经结束了,如果此时栈不为空,说明栈顶元素没有对应的右符号
}
return 0;
}