代码:
#include<stdio.h> #include<stdlib.h> #define MAX 100//存储空间初始分配量 #define MIN 10 typedef struct { char* base;//栈底指针 char* top;//栈顶指针 int stacksize; }SqStack; typedef struct QNote { char data; struct QNote *next; }QNote,*QueuePtr; typedef struct { QueuePtr front;//队头指针 QueuePtr rear;//队尾指针 }LinkQueue; void InitStack(SqStack *s) //构造一个空栈 { s->base=(char*)malloc(MAX*sizeof(char));//给base分配空间; s->top=s->base; s->stacksize=MAX; } void Push(SqStack *s,char e) //插入元素e为新的栈顶元素 { if(s->top-s->base>=MAX) //判断是否大于满栈; { s->base=(char*)realloc(s->base,(s->stacksize+MIN)*sizeof(char)); s->top=s->base+s->stacksize; s->stacksize+=MIN; } *(s->top)=e; s->top++; } void Pop(SqStack *s,char *e) //元素e出栈 { *e=*--s->top; } int StackEmpty(SqStack s) //判断栈是否为空 { if(s.top==s.base) return 1; else return 0; } void ClearStack(SqStack *s) //清空栈 { s->top=s->base; } void InitQueue(LinkQueue *q) //构造一个空队列 { q->front=q->rear=(QNote*)malloc(sizeof(QNote)); q->front->next=NULL; } void EnQueue(LinkQueue *q,char e) //插入元素e为新的队尾元素 { QNote *p; p=(QNote*)malloc(sizeof(QNote)); p->data=e; p->next=NULL; q->rear->next=p; q->rear=p; } void DeQueue(LinkQueue *q,char *e) //元素出队 { QNote *p; p=q->front->next; *e=p->data; q->front->next=p->next; if(q->rear==p) q->rear=q->front; free(p); } int QueueEmpty(LinkQueue q) //判断队列是否为空 { if(q.front==q.rear) return 1; else return 0; } void InStack(char* ch,SqStack *s) {//把字符数组从右至左压入栈中 int i,L=0; while(ch[L]!=' ') L++; for(i=L-1;i>=0;i--) Push(s,ch[i]); } int main() { int x1=1; printf("输入大魔王语言: "); while (x1==1) // { char A[]="sae"; //大写字母作为字符数组名存放小写字母 char B[]="tsaedsae"; char flag='0'; //flag用来标记处理括号 char e1,key,e2,e,i=0; int mark=; //标记输入的魔王语言是否在允许的范围之内 int f=1; // 判断括号是否匹配 char MoWang[100]=" "; //定义一个魔王变量,存放待解释的语言字符 SqStack S; //作为栈存储元素,为后续操作和输出做准备 SqStack temp; //用来处理括号外的元素 InitStack(&S); InitStack(&temp); LinkQueue Q; InitQueue(&Q); gets(MoWang); //变量MoWang存储输入的语言 InStack(MoWang,&S); //把要解释的魔王语言压入栈中 while(!StackEmpty(S)) //把魔王语言进行出栈,不符合语言的进行提示 { Pop(&S,&e1); if(e1=='(') { if(StackEmpty(S)) { printf("魔王语言错误! "); mark=0;f=0; break; } while(!StackEmpty(S)) { Pop(&S,&e1); if(e1==')') { if(i==0)//判断是否存在空括号(本程序设空括号为非法语言) f=0; break; } else if(!(e1>='a'&&e1<='z')&&!(e1>='A'&&e1<='Z')) { printf("魔王语言错误! "); mark=0; break; } i++; } if(mark==0) break; if(f!=1) { printf("魔王语言错误! "); break; } } else if(e1==')') { printf("魔王语言错误! "); mark=0; break; } else if(!(e1>='a'&&e1<='z')&&!(e1>='A'&&e1<='Z')) { printf("魔王语言错误! "); mark=0; break; } } if(mark==1&&f==1) //对符合语言规则的魔王语言进行规则处理 { ClearStack(&S); InStack(MoWang,&S); //把魔王语言从右至左压栈存放 while(!StackEmpty(S)) //栈不空时,用栈temp进行存储不带括号内元素的元素 { Pop(&S,&e1); if(e1=='B'||e1=='A') Push(&temp,e1); else if(e1=='(') //用队存储括号中的元素 { Push(&temp,flag); //有括号的话就用flag标记 Pop(&S,&e1); while(e1!=')') //把括号中的元素存入队列中 { EnQueue(&Q,e1); Pop(&S,&e1); } if(!QueueEmpty(Q)) DeQueue(&Q,&key); //将队头的元素赋值给key } else Push(&temp,e1); } while(!StackEmpty(temp)) //将魔王说的语言规则地压入栈s中 { Pop(&temp,&e1); if(e1!=flag) Push(&S,e1); //把括号外的元素压入栈s中 else { while(!QueueEmpty(Q)) //处理括号中的元素进栈 { DeQueue(&Q,&e2); Push(&S,key); Push(&S,e2); } Push(&S,key); //最后还要压一个key } } printf("解释后的语言为: "); while(!StackEmpty(S)) //依次出栈输出处理后的元素 { Pop(&S,&e); EnQueue(&Q,e); //元素进队是为了输出对应汉字 if(e=='B') printf("%s",B); else if(e=='A') printf("%s",A); else printf("%c",e); } printf(" "); while(!QueueEmpty(Q))//队列不为空的情况下。 { DeQueue(&Q,&e); switch(e) { case 't' : printf("天");break; case 'd' : printf("地"); break; case 's' : printf("上"); break; case 'a' : printf("一只"); break; case 'e' : printf("鹅"); break; case 'z' : printf("追"); break; case 'g' : printf("赶"); break; case 'x' : printf("下"); break; case 'n' : printf("蛋"); break; case 'h' : printf("恨"); break; case 'B' : printf("天上一只鹅地上一只鹅");break; case 'A' : printf("上一只鹅");break; default : printf("(无法翻译!)");break; } } printf(" "); } printf("再次输入魔王语言(按数字键0退出) "); scanf("%d",&x1); } return 0; }