符號配對 (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;
}