问题:
有一个魔王总是使用自己的一种非常精练而又抽象的语言讲话,没有人能听得懂,但他的语言是可以逐步解释成人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
(1) α -> β1β2…βm
(2)(θδ1δ2…δn)->θδnθδn-1… θδ1θ
在这两种形式中,从左到右均表示解释。试写一个魔王语言的解释系统,把他的话解释成人能听得懂的话。
基本要求:
用下述两条具体规则和上述规则形式(2)实现。
(1)B -> tAdA
(2)A -> sae
注:
大写字母表示魔王语言的词汇
小写字母表示人的语言词汇
希腊字母表示可以用大写字母或小写字母代换的变量。
魔王语言可含人的词汇。
例如: B(ehnxgz)B 解释成 tsaedsaeezegexenehetsaedsae
源码如下:
1 /* 2 * 魔王语言 3 * 栈----先进后出-----处理带括号的部分 4 * 队列--先进先出-----将对处理后的语言 5 * 2018.10.3 fang 6 */ 7 #include<stdio.h> 8 #include<stdlib.h> 9 #define STACK_INIT_SIZE 100; //存储空间初始分配量 10 #define STACKINCREMENT 10; //存储空间分配增量 11 #define NULL 0; 12 13 typedef struct Sqstack{ 14 char *base; 15 char *top; 16 int stacksize; 17 }sqstack; 18 19 typedef struct QNode{ 20 char data; 21 struct QNode *next; 22 }Qnode, *QueuePtr; 23 24 typedef struct LinkQueue{ 25 QueuePtr front; 26 QueuePtr rear; 27 }LinkQueue; 28 //初始化栈 29 void InitStack(sqstack *s); 30 //入栈 31 void push(sqstack *s,char e); 32 //获得栈顶元素 33 char getTop(sqstack *s); 34 //初始化队列 35 void InitQueue(LinkQueue *q); 36 //入队 37 void Enqueue(LinkQueue *q,char e); 38 //出队 39 char Dequeue(LinkQueue *q); 40 41 42 int main() { 43 sqstack *s; 44 LinkQueue *q; 45 int m, j; 46 int i = 0; 47 char c, language[100]; 48 q = (LinkQueue*)malloc(sizeof(LinkQueue)); 49 s = (sqstack*)malloc(sizeof(sqstack)); 50 InitStack(s); 51 InitQueue(q); 52 //① 首先,将魔王语言存放在language数组中 53 printf("\t\t*************** Devil's Language ***************\n\n\n"); 54 printf("\t\t请输入魔王语言:\t"); 55 while(c != '\n') { 56 scanf("%c",&c); 57 language[i] = c; 58 i++; 59 } 60 61 //② 然后,将数组中括号内元素入栈(括号里的元素放在栈中逆置) 62 //从第二位数字开始,每位数字后面都插入括号里数据的首字母 63 for(j=0;j<i-1;j++) { 64 if(language[j] == '(') { 65 m = j; //language[m+1]作为固定的首字母值 66 push(s,language[m+1]); 67 while(language[j+2] != ')') { 68 push(s,language[j+2]); 69 push(s,language[m+1]); 70 j++; 71 } 72 } 73 } 74 75 //③ 将数组中元素全部入队,遇到()先出栈再入队 76 for(j=0;j<i-1;j++) { 77 if(language[j] == '(') { 78 while(s->base != s->top) { 79 char e = getTop(s); 80 Enqueue(q,e); 81 } 82 while(language[j] != ')'){ 83 j++; 84 continue; 85 } 86 continue; 87 } 88 Enqueue(q,language[j]); 89 } 90 91 //④ 将队中的元素全部取出,逐个翻译 92 printf("\n\n\t\t翻译之后:\t"); 93 while(q->front != q->rear) { 94 char ch = Dequeue(q); 95 if(ch == 'A') printf("%s","sae"); 96 else if(ch == 'B') printf("%s","tsaedsae"); 97 else printf("%c",ch); 98 } 99 return 0; 100 } 101 102 103 104 105 106 //栈操作 107 void InitStack(sqstack *s) { 108 s->base = (char*) malloc(100 * sizeof(char)); 109 s->top = s->base; 110 s->stacksize = STACK_INIT_SIZE; 111 } 112 void push(sqstack *s,char e) { 113 //如果栈满 114 if(s->top - s->base >= s->stacksize) { 115 s->base = (char *)realloc(s->base,(s->stacksize+10)*sizeof(char)); 116 s->stacksize += STACKINCREMENT; 117 s->top = s->base + s->stacksize; 118 } 119 *(s->top) = e; 120 s->top++; 121 } 122 char getTop(sqstack *s) { 123 char e; 124 if(s->top-s->base == 0) 125 return -1; 126 e = *(s->top-1); 127 s->top--; 128 return e; 129 } 130 131 132 133 134 135 //队列操作 136 void InitQueue(LinkQueue *q){ 137 q->front = q->rear = (QueuePtr)malloc(sizeof(Qnode)); 138 if(!q->front) exit(-1); //内存分配失败 139 q->front->next = NULL; 140 } 141 142 void Enqueue(LinkQueue *q,char e){ 143 QueuePtr p = (QueuePtr)malloc(sizeof(Qnode)); 144 if(!p) exit(-1); //内存分配失败 145 p->data = e; 146 p->next = NULL; 147 q->rear->next = p; 148 q->rear = p; 149 } 150 151 char Dequeue(LinkQueue *q){ 152 char e; 153 if(q->front == q->rear) exit(0); 154 QueuePtr p = q->front->next; 155 e = p->data; 156 q->front->next = p->next; 157 if(q->rear == p) q->rear = q->front; 158 free(p); 159 return e; 160 }
测试: