代码:
#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]!='\0')
L++;
for(i=L-1;i>=0;i--)
Push(s,ch[i]);
}
int main()
{
int x1=1;
printf("输入大魔王语言:\n");
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]="\0"; //定义一个魔王变量,存放待解释的语言字符
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("魔王语言错误!\n");
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("魔王语言错误!\n");
mark=0;
break;
}
i++;
}
if(mark==0)
break;
if(f!=1)
{
printf("魔王语言错误!\n");
break;
}
}
else if(e1==')')
{
printf("魔王语言错误!\n");
mark=0;
break;
}
else if(!(e1>='a'&&e1<='z')&&!(e1>='A'&&e1<='Z'))
{
printf("魔王语言错误!\n");
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("解释后的语言为:\n");
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("\n");
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("\n");
}
printf("再次输入魔王语言(按数字键0退出)\n");
scanf("%d",&x1);
}
return 0;
}