符號配對 (20 分)

符號配對 (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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章