7-6 符号配对 (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<cstdio>
#include<stack>
#include<cstring>
using namespace std;
#define MaxSize 500
typedef char ElemType;
char symbol[130] = { 0 };
stack<ElemType>s;
void Judge(char c, char& ans)
{//判断是否匹配,如果不匹配则可以得到答案
	if (!s.empty() && symbol[c] == s.top()) s.pop();//匹配的话,消去
	else {
		/*注意两种情况:1.{[} 2.{]}
		1.扫描到}是应该是[失配,这毫无疑问
		2.扫描到]不应该是{失配而是本身失配。
		那如何区分两种情况呢,当栈内元素多于1个就肯定是栈顶的,因为栈内还有没有匹配的
		否则是它本身失配,因为栈内要么没有元素,
		要么只有一个元素可以在后面找到匹配,哪怕栈顶没有匹配,
		也是它本身失配符合最优解都不可能是栈内元素失配
		有点难理解,充分理解下栈。加油!!
		*/
		if (s.size() <= 1) ans = c;
		else ans = s.top();
	}
}
bool Is_left(char a[], int i)//判断左注释
{
	if (a[i] == '/' && a[i + 1] == '*') return true;
	return false;
}
bool Is_right(char a[], int i)//判断右注释
{
	if (a[i] == '*' && a[i + 1] == '/') return true;
	return false;
}
void Print(char c);//输出答案
int main()
{
	//建立一个双向映射,方便后续判断是否匹配
	symbol[')'] = '(';symbol['}'] = '{';
	symbol[']'] = '[';symbol['>'] = '<';//这是/*对应<,*/对应>;
	symbol['('] = ')';	symbol['{'] = '}';
	symbol['['] = ']';	symbol['<'] = '>';
	char str[1000];
	char ans = ' ';//存储失配的答案
	while (~scanf("%s", str))
	{
		if (str[0] == '.' && strlen(str) == 1) break;
		if (ans != ' ') continue;//找到了第一次失配了,那么只需要全部输入完就可以了。因为已经得到了答案
		for (int i = 0; i < strlen(str); ++i)
		{
			if (ans != ' ') break;//找到了就不找了
			if (str[i] == '{' || str[i] == '[' || str[i] == '(') s.push(str[i]);//左符号直接加
			else if (str[i] == '}' || str[i] == ']' || str[i] == ')') {//有符号看能否匹配
				Judge(str[i], ans);
			}
			else if (str[i] == '/' && Is_left(str, i))//左符合加进去
			{
				s.push('<');
				i++;//注意把两个字符变成一个 i要加2,所以这里要加1,然后循环在加1
			}
			else if (str[i] == '*' && Is_right(str, i))//右边的判断一下
			{
				Judge('>', ans);
				i++;
			}
			else if (str[i] == '/' && s.top() == '<')//注意这个特殊情况/*/,这里要对/看成是对左注释的失配
				ans = '<';
		}
	}
	//这里要注意啊,可能栈内还有一个失配的,但是没有扫描如{[]这种情况。所以要在判断一下
	if (!s.empty()) ans = s.top();
	Print(ans);
	return 0;
}
void Print(char c)//输出没什么好说的,按题目要求来,多搞几个判断就好了
{
	if (c == ' ') printf("YES\n");
	else {
		printf("NO\n");
		if (c == '<') printf("/*-?\n");
		else if (c == '>') printf("?-*/\n");
		else if (c == '{' || c == '(' || c == '[')
			printf("%c-?\n", c);
		else printf("?-%c\n", c);
	}
}

加油!!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值