数据结构-课程设计报告-魔王语言解释

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

题目:魔王语言解释
[问题描述]
有一个魔王总是使用自己的一种非常精练而抽象的语言讲话,没有人能听懂,但他的语言是可以逐步解释成人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
(1)α->β1β2……βm
(2)(θδ1δ2……δn)—>θδnθδn-1……θδ1θ
在这两种形式中,从左到右均表示解释。

试写一个魔王语言的解释系统,把他的话解释成人能听得懂的话;
[基本要求]
用下述两条具体规则和上述规则形式(2)实现。

设大写字母表示魔王语言的词汇;小写字母表示人的语言词汇;希腊字母表示可以用大写字母或小写字母代换的变量。

魔王语言可含人的词汇。

(1)B->tAdA
(2)A->sae
[测试数据]
B(ehnxgz)B解释成tsaedsaeezegexenehetsaedsae
若将小写字母与汉字建立下表所示的对应关系,则魔王说的话是:“天上一只鹅地上一只鹅鹅追鹅赶鹅下鹅蛋鹅恨鹅天上一只鹅地上一只鹅”。

[实现提示]
将魔王的语言自右至左进栈,总是处理栈顶字符。

若是开括号,则逐一出栈,将字母顺序入队列,直至闭括号出栈,并按规则要求逐一出队列再处理后入栈。

其他情形较简单,请读者思考应如何处理。

应首先实现栈和队列的基本操作。

[源代码]
#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
struct Stack{
char* base;
char* top;
int stacksize;
};
void InitStack(struct Stack &s){//构造栈
s.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}
void Push(struct Stack &s,char e){//压入元素
if(s.top-s.base>=STACK_INIT_SIZE){
s.base=(char*)realloc(s.base,(s.stacksize+STACK_INCREMENT)*sizeof(char));
s.top=s.base+s.stacksize;
s.stacksize+=STACK_INCREMENT;
}
*(s.top)=e;
s.top++;
}
void Pop(struct Stack &s,char &e){//取出元素
e=*--s.top;
}
int StackEmpty(struct Stack s){//栈是否为空
if(s.top==s.base){
return 1;
}
else{
return 0;
}
}
void ClearStack(struct Stack &s){
s.top=s.base;
}
struct Queue{
char data;
struct Queue* next;
};
struct LinkQueue{
struct Queue* front;
struct Queue* rear;
};
void InitQueue(struct LinkQueue &q){//构造队
q.front=q.rear=(struct Queue*)malloc(sizeof(struct Queue));
q.front->next=NULL;
}
void EnQueue(struct LinkQueue &q,char e){//元素入队
struct Queue* p;
p=(struct Queue*)malloc(sizeof(struct Queue));
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
}
void DeQueue(struct LinkQueue &q,char &e){//元素出队
struct Queue* 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(struct LinkQueue q){//队是否为空
if(q.front==q.rear){
return 1;
}
else{
return 0;
}
}
void InStack(char* ch,struct Stack &s){//把字符数组从右至左压入栈中int i,L=0;
while(ch[L]!='\0'){
L++;
}
for(i=L-1;i>=0;i--){
Push(s,ch[i]);
}
}
int main(){
int i=0;
char A[]="sae";
char B[]="tsaedsae";
char flag='0';//flag用来标记处理括号
int mark=1;
int f=0;
struct Stack S;
struct Stack temp;//用来处理括号外的元素
InitStack(S);
InitStack(temp);
struct LinkQueue Q;
InitQueue(Q);
char MoWang[100]="\0";
char e1,key,e2,e;
printf("请输入你想要解释的魔王语言:\n");
gets(MoWang);
InStack(MoWang,S);//把要解释的魔王语言压入栈中
while(!StackEmpty(S)){
Pop(S,e1);
if(e1=='('){
if(StackEmpty(S)){
printf("魔王语言错误!\n");
mark=0;
break;
}
while(!StackEmpty(S)){
Pop(S,e1);
if(e1==')'){
f=1;
break;
}
else if(!(e1>='a'&&e1<='z')&&!(e1>='A'&&e1<='Z')){ printf("魔王语言错误!\n");
mark=0;
break;
}
}
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)){//栈不空时
Pop(S,e1);
if(e1=='B'){
Push(temp,e1);
}
else if(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);
}
}
else{
Push(temp,e1);
f=0;
}
}
while(!StackEmpty(temp)){//边处理边进栈
Pop(temp,e1);
if(e1!=flag){//把括号外的元素压入中
Push(S,e1);
}
else{
while(!QueueEmpty(Q)){//处理括号中的元素进栈
DeQueue(Q,e2);
Push(S,key);
Push(S,e2);
}
if(f!=0){//最后还要压一个key
Push(S,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");
}
system("pause");
return 0;
}
[读者手册]
1、本程序的运行环境为dos操作系统,执行文件为“魔王解释语言.exe”。

2、进入演示程序后,即显示文本方式的用户界面
3、假设魔王语言为:tdsaexghnAtx
则可解释为:txtttsaetnthtgtztetatstdt
将其与汉字建立对应关系,则魔王说的话是:天下天天天上一只鹅天蛋天恨天赶天追天鹅天一只天上天地天。

[设计感想]
算法具体设计情况如下:一,总共有13个算法。

二,其中前三个算法是结构体的初始化,包括第一个是栈的结构体的定义,第二个和第三个是对单链队列--------队列的链式存储结构的初始化。

三,其中4—7是对于栈的一些基本操作,这里主要包括构造一个空栈InitStack()、插入元素e为栈顶元素Push()、若栈不空,则删除s的栈顶元素,用e返回其值Pop()、若栈S为空,则返回FALSE,否则返回TRUEStackEmpty()。

四,其中8—11是对于列队的一些基本操作,这里主要包括构造一个空队列InitQueue()、插入元素e为Q 的新的队尾元素EnQueue()、若队列不空,则删除Q的对头元素,用e返回其值,并返回OK;否则返回ERRORDeQueue()、若队列Q为空,则返回FALSE,否则返回TRUEQueueEmpty ()。

五,其中12、13个分别是逆序压栈InStack1()和顺序压栈InStack2()。

六,在魔王语言的算法编写的过程中,也遇到了一些麻烦,例如对于这些算法的综合以及各个算法之间的关系,另外还有一些小的问题:栈和队列的一些小小的联系,还有就是要注意一些在进行队列的指针的操作时,要注意指针的调用,同时开始时因为对于指针的一些用法及调用还有一些不太熟悉,因此有几个地方编写的时候遇到了无法执行的局面,后来又对指针的运算进行了一些改进,才使得指针对于数据元素的调用才比较灵活,从这次编写算法的过程中,自己发现自己对于C语言中的指针的一些基本的描述和执行的操作不是很明白,因此自己还要继续加强对指针的学习,希望下次再遇到指针的问题时能够顺利的解决。

11。

相关文档
最新文档