符号配对 (20 分)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44720323/article/details/101570690

符号配对 (20 分)


思路:
1、将数据全部都读入,然后预处理为只有(),{},[],/*/的形式。
2、利用栈来判断是否相符
其实本题的难点也是这两方面,读入数据.和\n比较麻烦。可以同getchar()和字符数组来处理。
二就是,再利用栈判断是否相符时,需要些很多的if和else if的结构,用来分辨多种条件。

由于我并没有这道题的权限,所以代码没有在OJ上跑过,但是三个例子均可成功,我也试过其他的例子也可以通过。

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/**
 * 栈带有头结点 
 */

//创建栈 
typedef struct Node *Stack;
struct Node{
	char Str;
	Stack Next;
};
//操作 
Stack CreateStack(); //创建节点
void Push(Stack ptr,char s); //入栈 
char Pop(Stack ptr); //出栈 
int IsEmpty(Stack p); //判断是不是空的 
void prepro(char *q,char *prep); //预处理 
char Look(Stack ptr); //查看栈顶元素 
char *ReadStr(); //读入数据 

int main()
{
	Stack p;
	char temp; //用来接收Pop 
	p = CreateStack();
//	char S[1000] = "void test(){int i, A[10];for (i=0; i<10;i++)/**/A[i] = i}].";
	char prep[200] = {0}; //预处理字符串 
	char *S;
	S = ReadStr();   //读入数据
	prepro(S,prep);  //预处理
//	printf("%s\n",prep);
	char *q = prep;
	//判断错误 
	while(*q)
	{
		if(*q == '(' || *q == '{' || *q == '[' ){	//入栈 
			Push(p,*q);
			q++;
			continue;
		} else if(*q == '/' && *(q+1) == '*'){	//处理/* 
			Push(p,'/');
			q = q+2; //可能越界 
			continue;
		} else if(*q == ')'){	//处理 ) 
			temp = Look(p);
			if(temp == '0') {printf("NO\n?-)\n");return 0;}
			if(temp == '(') {Pop(p);}
			else {printf("NO\n%c-?\n",temp);return 0;} 
			q++;
			continue;
		} else if(*q == ']'){	//处理 ] 
			temp = Look(p);
			if(temp == '0') {printf("NO\n?-]\n");return 0;}
			if(temp == '[') {Pop(p);}
			else {printf("NO\n%c-?\n",temp);return 0;} 
			q++;
			continue;
		} else if(*q == '}'){	//处理 } 
			temp = Look(p);
			if(temp == '0') {printf("NO\n?-}\n");return 0;}
			if(temp == '{') {Pop(p);}
			else {printf("NO\n%c-?\n",temp);return 0;} 
			q++;
			continue;
		} else if(*q == '*' && *(q+1) == '/'){	//处理 */ 
			temp = Look(p);
			if(temp == '0') {printf("NO\n?-*/\n");return 0;}
			if(temp == '/') {Pop(p);}
			else {printf("NO\n%c-?\n",temp);return 0;} 
			q = q+2;
			continue;
		} else if(*q == '/' && *(q-1) == '*'){	//处理 /*/ 
			printf("NO\n/*-?\n");
			return 0;
		} else {q++;continue;}
	}
	//用来判断,配对完后栈是不是空的 
	if(!IsEmpty(p)){
		while(p->Next != NULL)
		{
			temp = Pop(p);
		}
		printf("NO\n%c-?\n",temp);
	}else 
		printf("YES\n");
	return 0;
} 

//创建结点 
Stack CreateStack()
{
	Stack p;
	p = (Stack)malloc(sizeof(struct Node));
	p->Str = '\0';
	p->Next = NULL;
	return p;
}

//入栈 
void Push(Stack ptr,char s)
{
	Stack p;
	p = CreateStack();
	p->Str = s;
	p->Next = ptr->Next;
	ptr->Next = p;
}
 
//出栈 
char Pop(Stack ptr)
{
	char s;
	if(IsEmpty(ptr)) return '0'; //返回值 
	Stack p = ptr->Next;
	s = p->Str;
	ptr->Next = p->Next;
	free(p);
	return s;
}

//判断是不是空的 
int IsEmpty(Stack p)
{
	return (p->Next == NULL); 
} 

//预处理 
void prepro(char *S,char *prep)
{
	char temp_prep[200];
	char *q = S;
	char temp[2] = "1";
	while(*q) //将无关的字符去除 
	{
		if(*q == '(' || *q == ')'   || *q == '{'|| *q == '}' || \
			*q == '[' || *q == ']' || *q == '/'|| *q == '*')
		{
			temp[0] = *q;
			strncat(temp_prep,temp,1);		
		}
		q++;
	}
	q = temp_prep;
	while(*q) //将*代表乘法的去除 
	{
		if(*q == '*' && *(q-1) == '*' && *(q+1) == '*') q++; //处理/***/ 处理不了/****/ 
		if(*q == '*' && (*(q-1) == '/' || *(q-1) == '*') && (*(q+1) == '/' || *(q+1) == '*'))
		{
			temp[0] = *q;
			strncat(prep,temp,1);
		}
		else if(*q == '(' || *q == ')'   || *q == '{'|| *q == '}' || \
			*q == '[' || *q == ']' || *q == '/')
		{
			temp[0] = *q;
			strncat(prep,temp,1);
		}
		q++;
	}
} 

char Look(Stack ptr)
{
	if(IsEmpty(ptr)) return '0'; //返回值 
	Stack p = ptr->Next;
	return p->Str;
} 

//读入数据
char *ReadStr()
{
	char *Str;
	char *p;
	Str = (char*)malloc(sizeof(char)*1000);
	char c;
	int i=0;
	while(1)
	{
	    c = getchar();
		Str[i++] = c;
		//Str[i-2]注意下标的判断 
		if(c == '\n' && Str[i-2] == '.')
		{
			break;
		}
	}
	Str[i] = '\0';
	p = Str;
	while(*p)
	{
		if(*p == '\n')
		{
			*p = 'a';
		}
		p++;
	}
	*p = '\0';
	return Str;
}

猜你喜欢

转载自blog.csdn.net/weixin_44720323/article/details/101570690