7-6 符号配对 (24 分)

在这里插入图片描述

这道题起初我看着也也觉得很复杂,觉得有多种情况,后来经过自己模拟做题,发现其实也就是三种,换句话来说,好像只要实现了题目给的三个样例就能全部AC,学生党不知道如何获得测试点,如果推测有错欢迎指正
在这里插入图片描述

这道题用c++来做雀食代码量会少一点,但是c语言做起来也没有复杂多少,当然如果是c++大佬当我没说,反正我用c++做的时候也是遍历,c语言做的时候也是要遍历,总之,我就只会遍历。老师要求用c语言那咱就用c语言完成一遍。
我代码的思路是:
1.先遍历整段字符串,遇到符号条件的符号都存进一个数组temp。
2.数组实现一个栈stack,在遍历已经存好的字符数组temp时,遇到左符号入栈,遇到右符号出栈,不符合的符号flag=0,直接跳出循环不用继续遍历temp了。
3.flag的值发生改变或者temp数组遍历完了之后进如判断步骤。
(1)如果temp数组遍历完了栈为空,top==0(我的代码中top的初值为0,也可以是-1,看个人喜好)而且此时flag的值还是1,就么就是yes完全匹配好了无错误。
(2)如果已经结束遍历(比如flag=0)top!=0也就是栈不空的情况,此时就直接是默认左符号不配对的情况,不要问我为什么,问出题人,我手动试过,附上运行结果:
在这里插入图片描述
很明显代码运行完符号配对应该是?-],但是原理是遍历到‘]’时,符号和栈中的’{‘不配对,就直接flag=0;跳过了。所以这就是为什么说题目只要结束遍历后栈中不为空,就直接默认是左符号的问题。
(3)最后一种情况就更容易理解了,就是栈已经为空了,也没有左符号可以进去了,但是temp后面还有右符号,所以就是右符号出了问题。
4.最后一步就按照题目的要求输出结果就行啦。芜湖!

//脑子不好的林林后
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int top=0;//作栈顶
int main()
{
	char stack[500];//存储左半边的符号
	char temp[500];//存储字符串里的全部要检查的符号
	char str[500];//保留每一行的输入字符.
	int j=0;
	int flag=1;//最终判断
	while(gets(str))
	{
		if(str[0]=='.')break;//题目条件,后面的一个回车判断可不加也能全ac
		for(int i=0;i<strlen(str);i++)//gets只能检查一行,所以str就是分别存储了一行行的字符再判断
		{
			if(str[i]=='('||str[i]=='['||str[i]=='{'||str[i]==')'||str[i]==']'||str[i]=='}')
			{
				temp[j++]=str[i];
			}
			else if(str[i]=='/'&&str[i+1]=='*')
			{
				temp[j++]='a';
				i++;
			}
			else if(str[i]=='*'&&str[i+1]=='/')
			{
				temp[j++]='b';
				i++;
			}
		}

	}//至此,要检查的符号已经全部存到了temp里面.下面只需要利用栈的知识判断temp里面的字符
	char error;//定义一个字符,后面要用。
	for(int i=0;i<j;i++)//遍历temp数组。
	{
		if(temp[i]=='('||temp[i]=='['||temp[i]=='{'||temp[i]=='a')//将一对符号的左边值存到stack数组里面
		{
			stack[top++]=temp[i];
		}
		if(temp[i]==')')//遇到右半边的符号就想办法再数组stack里边实现出栈功能
		{
			if(stack[top-1]=='(')top--;//stack数组最后存入的符号符合条件就top--,等下次遇到左半边的符号,原来的值就会被新的值覆盖就实现了出栈功能
			else//如果出现不等的情况那就直接出结果了
			{
				error=temp[i];
				flag=0;//已经不满足条件了
				break;
			}
			
		}
		if(temp[i]==']')//下面的情况就是如法炮制
			{
				if(stack[top-1]=='[')top--;
				else
				{
					error=temp[i];
					flag=0;
					break;
				}
			}
		if(temp[i]=='}')
			{
				if(stack[top-1]=='{')top--;
				else
				{
					error=temp[i];
					flag=0;
					break;
				}
			}
		if(temp[i]=='b')
			{
				if(stack[top-1]=='a')top--;
				else
				{
					error=temp[i];
					flag=0;
					break;
				}
			}

	}
	if(flag==1&&top==0)printf("YES");//没有错误的情况stack里面的字符都已经配对完毕了,此时flag=1,top=-
	else//flag=0时有两种情况一种是top!=0的错误情况也就是不配对的符号在中间,此时题目好像是默认左边边符号配对也就是列如(-?
	{
		printf("NO\n");
		if(top!=0)//
		{
			if(stack[top-1]=='(')printf("%c-?",stack[top-1]);//输出格式注意题目要求就没问题了
            if(stack[top-1]=='[')printf("%c-?",stack[top-1]);
            if(stack[top-1]=='{')printf("%c-?",stack[top-1]);
            if(stack[top-1]=='a')printf("/*-?");
		}
		else//此时top==0了也就是stack里面的符号也就配对完了,但是还有一个符号没有配对此时就是右边符号出了问题啦
		{
			if(error==')')printf("?-%c",error);
            if(error==']')printf("?-%c",error);
            if(error=='}')printf("?-%c",error);
            if(error=='b')printf("?-*/");
		}
	}
	return 0;
}
在 C 语言源程序中,符号配对是非常重要的,特别是用于控制结构如注释、条件语句和循环等。DS课程组的题目要求检测四种特定的符号对:`/*` 与 `*/`(多行注释)、`( ` 与 `)`(圆括号)、`[ ` 与 `]`(方括号)以及 `{ ` 与 `}`(花括号)。为了编写这样一个程序,你可以遍历源代码字符串,并维护一个栈来存储当前未关闭的左符号。 下面是一个简单的伪代码示例: ```c #include <stdio.h> #include <string.h> bool is_pair(char open_char, char close_char) { return open_char == '{' && close_char == '}'; } void check_pairs(const char* code) { stack<char> pairs; for (int i = 0; code[i]; i++) { if (code[i] == '/' && code[i + 1] == '*') { // 处理 /* */ int j = i; while (code[j] != '*' || code[j + 1] != '/') { j++; if (j == strlen(code)) break; } if (j == strlen(code)) return false; // 注释结束前未找到结束符 i = j + 2; // 跳过结束的 */ 对 } else if (is_pair(code[i], code[i+1])) { pairs.push(open_char); } else if (!pairs.empty() && code[i] == close_char) { if (pairs.top() != open_char) return false; pairs.pop(); } else { // 如果遇到不是成对的字符,且栈为空或者非成对字符,返回false if (pairs.empty()) return false; } } // 检查栈是否为空,所有符号都已正确配对 return pairs.empty(); } int main() { const char* source_code = "your_c_code_here"; if (check_pairs(source_code)) { printf("符号配对正确。\n"); } else { printf("符号配对错误。\n"); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值