PTA 7-1 符号配对 (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<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;
}

本期分享到这里就结束啦,大家如果对小编的代码有疑问或者想要小编做其他的程序,都欢迎来私信小编呀!

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值