数据结构课程设计:魔王语言解释

1.【问题描述】

有一个魔王总是使用自己的一种非常精练而抽象的语言讲话,没有人能昕得懂,但他的语言是可以逐步解释成人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:

(1)α->β1β2β3

(2)(θδ1δ2δ3)->θδ1θδ2θδ3θ

在这两种形式中,从左到右均表示解释。试写一个魔王语言的解释系统,把他的话解释成人能听得懂的话。

2.【基本要求】

用下述两条具体规则和上述规则形式(2)实现。设大写字母表示魔王语言的词汇;小写字母表示人的语言词汇;希腊字母表示可以用大写字母或小写字母代换的变量。魔王语言可含人的词汇。

(1)B->tAdA

(2)A->sae

3. 【测试数据】

B(ehnxgz)B解释成tsaedsaeezegexenehetsaedsae

若将小写字母与汉字建立下表所示的对应关系,则魔王说的话是“天上一只鹅地上一只鹅鹅追鹅赶鹅下鹅蛋鹅恨鹅天上一只鹅地上一只鹅”。

t

d

s

a

e

z

g

x

n

h

一只

 

#include <iostream>  
#include <string>  
using namespace std;  
//类不是实体,是一种抽象类型,不占存储空间  
class SqStack    //使用链表实现栈类,SqStack为类名  
{  
	private:        //声明为私有的 
	    struct Node //声明一个名为Node的结构体类型 
	    {  
	        int content; //content,内容 
	        char word;  
	        Node *next;  
	    }   ;  
	    Node *top,*base;  
	public:  
	    SqStack();  
	    virtual ~SqStack();  
	    bool push(char e);  
	    bool pop(char &e);  
	    bool StackEmpty();  
};  
  
//栈的基本操作  
SqStack::SqStack()     //::为作用域限定符,用它声明函数属于哪个类的 
{  
    top=base=new Node;  
}  
  
SqStack::~SqStack()  
{  
  
}  
//bool的优点是将错误返回给调用环境,由调用环境决定程序的下一步走向
//返回0/1
 
bool SqStack::push(char e)    //压栈操作  
{  
    Node *p=new Node;  
	//用new运算符动态建立一个对象,与delete配合使用 
    if(p==NULL)  
    {  
        cout<<"Stack is overflow"<<endl;  
        return false;  
    }  
    else  //入栈操作
    {  
        p->word=e;   
        p->next=top;  
        top=p;  
        return true;  
    }  
}  
  
bool SqStack::pop(char &e)    //出栈操作  
{     
    if(top==NULL)  
    {  
        cout<<"Stack is empty"<<endl;  
        return false;  
    }  
    else  
    {  
        if(top==base)  
            return false;  //栈空时 
        Node *p=top;       //p指针指向栈顶元素 
        top=top->next;     //指针下移,元素出栈 
        e=p->word;         //返回值e 
        delete p;          //删除new出来的p 
        return true;  
    }  
}  
  
bool SqStack::StackEmpty()  //判断是否为空栈  
{  
    return top==base;       //top==base时栈空 
}  
  
class SqQueue    //使用链表实现队列类  
{  
	private:  
	    struct Node  
	    {  
	        int content;  
	        char word;  
	        Node *next;  
	    }   ;  
	    Node *front,*rear;  
	public:  
	    SqQueue();  
	    virtual ~SqQueue();  
	    bool EnQueue(char e);  
	    bool DeQueue(char &e);  
	    bool QueueEmpty();  
	    void OutQueue();  
	    void EnQueue_A();  
	    void EnQueue_B();  
};  
  
//队列的基本操作  
SqQueue::SqQueue()  
{  
    front=rear=new Node;  //初始化一个空队列 
}  
  
SqQueue::~SqQueue()  
{  
  
}  
  
bool SqQueue::EnQueue(char e)    //入队列  
{  
    Node *p=new Node;  
    if(p==NULL)  
    {  
        cout<<"Queue is overflow"<<endl;  
        return false;   
    }  
    else  
    {  
        p->word=e;  
        rear->next=p;  
        rear=p;  
        p->next=NULL;  
        return true;  
    }  
}  
bool SqQueue::DeQueue(char &e)    //出队列  
{  
    if(front==NULL)  
    {  
        cout<<"Queue is empty"<<endl;  
        return false;  
    }  
    else  
    {  
        Node *p=front;  
        front=front->next;  
        e=p->word;  
        delete p;  
        return true;  
    }  
}  
  
void SqQueue::OutQueue()    //输出队列中的数据  
{  
    for(Node *p=front->next;p!=NULL;p=p->next)
	{cout<<p->word;}
	cout<<endl<<endl;
	cout<<"其对应的汉语为:"<<endl<<endl; 
	for(Node *p=front->next;p!=NULL;p=p->next)
	{
		if(p->word=='t')cout<<"天";
		 else if(p->word=='d')cout<<"地";
		 else if(p->word=='s')cout<<"上";
		 else if(p->word=='a')cout<<"一只";
		 else if(p->word=='e')cout<<"鹅";
		 else if(p->word=='z')cout<<"追";
		 else if(p->word=='g')cout<<"赶";
		 else if(p->word=='x')cout<<"下";
		 else if(p->word=='n')cout<<"蛋";
		 else if(p->word=='h')cout<<"恨"; 
	}
    cout<<endl<<endl;  
}  
  
bool SqQueue::QueueEmpty()  
{  
    return front==rear;  
	//front==rear时队列为空 
}  
  
void SqQueue::EnQueue_A()  
{  
    EnQueue('s');  
    EnQueue('a');  
    EnQueue('e');  
}  
  
void SqQueue::EnQueue_B()  
{  
    EnQueue('t');  
    EnQueue_A();  
    EnQueue('d');  
    EnQueue_A();  
}  
  
bool read_language(SqStack &S)        
//将魔王语言倒置压入栈中,这样出栈的时候就是正常顺序  
{  
    int i,n,left=0,right=0;  
    string m;   
    cout<<"请输入魔王语言:"<<endl;  
    while(cin>>m)
    {
    	n=m.length();      //求字符串长度  
		for(i=0;i<n;i++)  //统计出左右括号的数量 
		{  
		    if(m[i]=='(')  
		        left++;  
		    else if(m[i]==')')  
		        right++;  
		}  
		if(left!=right)  
		    return false;  
		for(i=n-1;i>=0;i--)  
		{  
		    S.push(m[i]);  
		}  
		return true;    	
	}
}  
  
void push_and_pop(SqStack &S1,SqStack &S2)      
//处理规则2,也就是处理一个完整括号内的内容  
{  
    char e,e1;  
    SqStack S3;    //栈S3作为进行转换的中间变量  
    SqStack();     //建了一个空栈,也只是一个节点 
    while(!S1.StackEmpty())  //当栈不为空 
    {  
        S1.pop(e);  
        if(e=='(')  
        {  
            S1.pop(e);  
            e1=e;       
		//e1中保存的就是魔王语言中(右边的第一个字母,就是第二种规则中的θ)  
            if(e!=')')  
                S1.pop(e);//不是右括号时继续出栈  
            while(e!=')')  
            {  
                S3.push(e); //在S3中存入出栈的元素,入栈操作       
                S1.pop(e);  //S1继续出栈 
            }   
            while(!S3.StackEmpty())  
            {  
                S2.push(e1);
				//根据第二种解释规则,将θ进行多次压栈操作  
                S3.pop(e);  
                S2.push(e);  
            }  
            S2.push(e1);  
        }  
    }  
}  
  
  
int main()  
{  
    char e;  
    bool flag;  
    SqStack S,S1,S2; //用栈类定义三个结构体变量 
    SqQueue Q;       //用队列类定义一个结构体变量Q 
    SqStack();       //建一个空栈 
    SqQueue();       //建一个空队列 
    cout<<"          ======================================="<<endl;
    cout<<"          ======================================="<<endl;
    cout<<"          ||           欢迎使用                ||"<<endl;
    cout<<"          ||         魔王语言翻译              ||"<<endl;
	cout<<"          ======================================="<<endl;
	cout<<"          ======================================="<<endl;
	cout<<endl<<endl;
	while(1) 
	{
		Start:flag=read_language(S);//读入魔王语言,存入栈S中
	
		if(!flag)  
	    {  
	        cout<<"括号不匹配,无法解释!"<<endl<<endl;
			goto Start;      
	    }  
	    while(!S.StackEmpty()) //当S栈不为空 
	    {  
	        S.pop(e);          //S中元素出栈 
	        if(e==')')         //当元素是右括号 
	        {  
	            S1.push(e);    //S1将该元素入栈 
	            S2.pop(e);     //S2将元素出栈 
	            while(e!='(')  //当S2出栈的不是左括号 
	            {  
	                S1.push(e);//S1将元素入栈 
	                S2.pop(e); //S2将元素出栈 
	            }  
	            if(e=='(')     //当S2出栈的是左括号 
	                S1.push(e);  //S1将左括号入栈
				//S1内是一个完整括号内容,用第二种规则处理
				//S1栈顶是左括号,栈底是右括号 
	            push_and_pop(S1,S2);  
	        }  
	        else  
	            S2.push(e); 
			//若S出栈的不是右括号,S2就将其入栈 
	    }  
	//S2存储的是经过第二种处理后的魔王语言 
	//魔王语言的前面部分在栈S2的底部,后面部分在栈S2的顶部,需要转换一下
	//转换后存入S中 
		while(!S2.StackEmpty())  
	    {  
	        S2.pop(e);  
	        S.push(e);    
			//魔王语言的后面部分在栈S的底部,前面部分在栈S的顶部  
	    }  
	  
	    //上面的操作进行的是第二种解释规则  
	    //下面的操作进行的是第一种解释规则  
	    while(!S.StackEmpty())  
	    {  
	        S.pop(e);  
	        if(e=='A')           //如果出栈的是A 
	            Q.EnQueue_A();   //就将sae入队列,即进行第一种解释 
	        if(e=='B')           //如果出栈的是B 
	            Q.EnQueue_B();   //就将tAtA入队列 
	        else  
	            Q.EnQueue(e);    //否则的话只将出栈元素入队列就好 
	    }  
	    cout<<"魔王语言可以初步解释为:"<<endl<<endl;  
	    Q.OutQueue();    //先进先出,输出队列中经过第一种处理的魔王语言
             
    	cout<<"感谢您使用魔王语言解释程序,您可以继续输入:)"<<endl<<endl;
	}   
    return 0;  
} 




  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1.问题分析和任务定义 1.1问题分析 有一个魔王总是使用自己的一种非常精练抽象语言讲话没有人能听得懂,但他的语言是可以逐步解释人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的: (1)α→β1β2…βm (2)(θδ1δ2…δn)→θδnθδn-1…θδ1θ 在这两种形式中,从左到右均表示解释。试写一个魔王语言解释系统,用下述两条具体规则和上述规则形式(2)实现,把他的话解释人能听得懂的话。 (1)B→tAdA (2)A→sae t d s a e z g x n h 天 地 上 一只 鹅 追 赶 下 蛋 恨 1.2任务定义 该问题要求输入一句魔王说的话后,能够将他的话翻译成人能听得懂的话,并将其输出,由于题中只给出了A和B的转换规则,以及字母:t,d,s,a,e,z,g,x,n,h,d所对应的汉字,所以输入的魔王的话只能是上述字符与括号所组成的字符串,否则导致不能翻译。要求能输出提示“非法输入!请重新输入魔王说的话:”,直至输入符合要求的魔王语言。输入了符合要求的魔王语言后,会输出相应的一组汉字。 测试数据: a.用于正确性检测的合法数据: B(ehnxgz)B解释成tsaedsaeezegexenehetsaedsae 若将小写字母与汉字建立上表所示的对应关系,则输出的结果为:“天上一只鹅地上一只鹅鹅追鹅赶鹅下鹅蛋鹅恨鹅天上一只鹅地上一只鹅。” b.用于健壮性检测的非法输入数据: EKwr

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值