魔王语言解释

 [问题描述]
有一个魔王总是使用自己的一种非常精练而又抽象的语言讲话,没有人能听得懂,但他的语言是可以逐步解释成人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:
(1) α -> β1β2…βm
(2)(θδ1δ2…δn)->θδnθδn-1… θδ1θ
在这两种形式中,从左到右均表示解释。试写一个魔王语言的解释系统,把他的话解释成人能听得懂的话。
[基本要求]
用下述两条具体规则和上述规则形式(2)实现。设大写字母表示魔王语言的词汇;小写字母表示人的语言词汇;希腊字母表示可以用大写字母或小写字母代换的变量。魔王语言可含人的词汇。
(1)B -> tAdA
(2)A -> sae
[测试数据]
B(ehnxgz)B解释成tsaedsaeezegexenehetsaedsae

解题思路:

        将魔王语言作为一个字符串读入进来,首先检查括号是否匹配,如果不匹配就无法解释。如果匹配,然后将字符串从尾到头依次压入栈S中,将栈S中的内容依次弹出压入栈S2中,直至遇到右括号,将其压入栈S1中,并将栈S2弹出依次压入栈S1中,直至遇到左括号压入栈S1中,这样栈S1中存放的内容就是匹配的第一个内重括号,将栈S1栈顶元素左括号弹出,将左括号下面的那个元素保存在e1变量中,然后将其他元素弹出依次压入栈S3中,在将e1与栈S3中依次弹出的元素压入栈S2中,重复这个过程,直至将魔王语言中所有的括号都处理完为止,所以这个思路可以处理多重括号嵌套的问题。。

完整的实现代码如下:

  1. #include "iostream"   
  2. #include "string"   
  3. using namespace std;  
  4.   
  5. class SqStack    //使用链表实现栈类   
  6. {  
  7. private:  
  8.     struct Node  
  9.     {  
  10.         int content;  
  11.         char word;  
  12.         Node *next;  
  13.     }   ;  
  14.     Node *top,*base;  
  15. public:  
  16.     SqStack();  
  17.     virtual ~SqStack();  
  18.     bool push(char e);  
  19.     bool pop(char &e);  
  20.     bool StackEmpty();  
  21. };  
  22.   
  23. //栈的基本操作   
  24. SqStack::SqStack()  
  25. {  
  26.     top=base=new Node;  
  27. }  
  28.   
  29. SqStack::~SqStack()  
  30. {  
  31.   
  32. }  
  33.   
  34. bool SqStack::push(char e)    //压栈操作   
  35. {  
  36.     Node *p=new Node;  
  37.     if(p==NULL)  
  38.     {  
  39.         cout<<"Stack is overflow"<<endl;  
  40.         return false;  
  41.     }  
  42.     else  
  43.     {  
  44.         p->word=e;  
  45.         p->next=top;  
  46.         top=p;  
  47.         return true;  
  48.     }  
  49. }  
  50.   
  51. bool SqStack::pop(char &e)    //出栈操作   
  52. {     
  53.     if(top==NULL)  
  54.     {  
  55.         cout<<"Stack is empty"<<endl;  
  56.         return false;  
  57.     }  
  58.     else  
  59.     {  
  60.         if(top==base)  
  61.             return false;  
  62.         Node *p=top;  
  63.         top=top->next;  
  64.         e=p->word;  
  65.         delete p;  
  66.         return true;  
  67.     }  
  68. }  
  69.   
  70. bool SqStack::StackEmpty()  //判断是否为空栈   
  71. {  
  72.     return top==base;  
  73. }  
  74.   
  75. class SqQueue    //使用链表实现队列类   
  76. {  
  77. private:  
  78.     struct Node  
  79.     {  
  80.         int content;  
  81.         char word;  
  82.         Node *next;  
  83.     }   ;  
  84.     Node *head,*last;  
  85. public:  
  86.     SqQueue();  
  87.     virtual ~SqQueue();  
  88.     bool EnQueue(char e);  
  89.     bool DeQueue(char &e);  
  90.     bool QueueEmpty();  
  91.     void OutQueue();  
  92.     void EnQueue_A();  
  93.     void EnQueue_B();  
  94. };  
  95.   
  96. //队列的基本操作   
  97. SqQueue::SqQueue()  
  98. {  
  99.     head=last=new Node;  
  100. }  
  101.   
  102. SqQueue::~SqQueue()  
  103. {  
  104.   
  105. }  
  106.   
  107. bool SqQueue::EnQueue(char e)    //入队列   
  108. {  
  109.     Node *p=new Node;  
  110.     if(p==NULL)  
  111.     {  
  112.         cout<<"Queue is overflow"<<endl;  
  113.         return false;   
  114.     }  
  115.     else  
  116.     {  
  117.         p->word=e;  
  118.         last->next=p;  
  119.         last=p;  
  120.         p->next=NULL;  
  121.         return true;  
  122.     }  
  123. }  
  124. bool SqQueue::DeQueue(char &e)    //出队列   
  125. {  
  126.     if(head==NULL)  
  127.     {  
  128.         cout<<"Queue is empty"<<endl;  
  129.         return false;  
  130.     }  
  131.     else  
  132.     {  
  133.         Node *p=head;  
  134.         head=head->next;  
  135.         e=p->word;  
  136.         delete p;  
  137.         return true;  
  138.     }  
  139. }  
  140.   
  141. void SqQueue::OutQueue()    //输出队列中的数据   
  142. {  
  143.     for(Node *p=head->next;p!=NULL;p=p->next)  
  144.         cout<<p->word;  
  145.     cout<<endl;  
  146. }  
  147.   
  148. bool SqQueue::QueueEmpty()  
  149. {  
  150.     return head==last;  
  151. }  
  152.   
  153. void SqQueue::EnQueue_A()  
  154. {  
  155.     EnQueue('s');  
  156.     EnQueue('a');  
  157.     EnQueue('e');  
  158. }  
  159.   
  160. void SqQueue::EnQueue_B()  
  161. {  
  162.     EnQueue('t');  
  163.     EnQueue_A();  
  164.     EnQueue('d');  
  165.     EnQueue_A();  
  166. }  
  167.   
  168. bool read_language(SqStack &S)        //将魔王语言倒置压入栈中   
  169. {  
  170.     int i,n,left=0,right=0;  
  171.     string m;   
  172.     cout<<"请输入魔王语言:"<<endl;  
  173.     cin>>m;  
  174.     n=m.length();      //求字符串长度   
  175.     for(i=0;i<n;i++)  
  176.     {  
  177.         if(m[i]=='(')  
  178.             left++;  
  179.         else if(m[i]==')')  
  180.             right++;  
  181.     }  
  182.     if(left!=right)  
  183.         return false;  
  184.     for(i=n-1;i>=0;i--)  
  185.     {  
  186.         S.push(m[i]);  
  187.     }  
  188.     return true;  
  189. }  
  190.   
  191. void push_and_pop(SqStack &S1,SqStack &S2)      //处理规则2   
  192. {  
  193.     char e,e1;  
  194.     SqStack S3;    //栈S3作为进行转换的中间变量   
  195.     SqStack();  
  196.     while(!S1.StackEmpty())  
  197.     {  
  198.         S1.pop(e);  
  199.         if(e=='(')  
  200.         {  
  201.             S1.pop(e);  
  202.             e1=e;       //e1中保存的就是魔王语言中(右边的第一个字母,就是第二种规则中的θ   
  203.             if(e!=')')  
  204.                 S1.pop(e);  
  205.             while(e!=')')  
  206.             {  
  207.                 S3.push(e);        
  208.                 S1.pop(e);  
  209.             }   
  210.             while(!S3.StackEmpty())  
  211.             {  
  212.                 S2.push(e1);    //根据第二种解释规则,将θ进行多次压栈操作   
  213.                 S3.pop(e);  
  214.                 S2.push(e);  
  215.             }  
  216.             S2.push(e1);  
  217.         }  
  218.     }  
  219. }  
  220.   
  221.   
  222. int main(void)  
  223. {  
  224.     char e;  
  225.     bool flag;  
  226.     SqStack S,S1,S2;  
  227.     SqQueue Q;  
  228.     SqStack();  
  229.     SqQueue();  
  230.     flag=read_language(S);     //读入魔王语言   
  231.     if(!flag)  
  232.     {  
  233.         cout<<"括号不匹配,无法解释!"<<endl;  
  234.         system("pause");  
  235.         return 0;  
  236.     }  
  237.     while(!S.StackEmpty())  
  238.     {  
  239.         S.pop(e);  
  240.         if(e==')')  
  241.         {  
  242.             S1.push(e);  
  243.             S2.pop(e);  
  244.             while(e!='(')  
  245.             {  
  246.                 S1.push(e);  
  247.                 S2.pop(e);  
  248.             }  
  249.             if(e=='(')  
  250.                 S1.push(e);  
  251.             push_and_pop(S1,S2);  
  252.         }  
  253.         else  
  254.             S2.push(e);  
  255.     }  
  256.    //魔王语言的前面部分在栈S2的底部,后面部分在栈S2的顶部,需要转换一下   
  257.     while(!S2.StackEmpty())  
  258.     {  
  259.         S2.pop(e);  
  260.         S.push(e);    //魔王语言的后面部分在栈S的底部,前面部分在栈S的顶部   
  261.     }  
  262.   
  263.     //上面的操作进行的是第二种解释规则   
  264.     //下面的操作进行的是第一种解释规则   
  265.     while(!S.StackEmpty())  
  266.     {  
  267.         S.pop(e);  
  268.         if(e=='A')  
  269.             Q.EnQueue_A();  
  270.         if(e=='B')  
  271.             Q.EnQueue_B();  
  272.         else  
  273.             Q.EnQueue(e);  
  274.     }  
  275.     cout<<"魔王语言可以解释为:"<<endl;  
  276.     Q.OutQueue();  
  277.     system("pause");  
  278.     return 0;  
  279. }  
#include "iostream"
#include "string"
using namespace std;

class SqStack    //使用链表实现栈类
{
private:
	struct Node
	{
		int 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 SqStack::push(char e)    //压栈操作
{
	Node *p=new Node;
	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;
		top=top->next;
		e=p->word;
		delete p;
		return true;
	}
}

bool SqStack::StackEmpty()  //判断是否为空栈
{
	return top==base;
}

class SqQueue    //使用链表实现队列类
{
private:
	struct Node
	{
		int content;
		char word;
		Node *next;
	}   ;
	Node *head,*last;
public:
	SqQueue();
	virtual ~SqQueue();
	bool EnQueue(char e);
	bool DeQueue(char &e);
	bool QueueEmpty();
	void OutQueue();
	void EnQueue_A();
	void EnQueue_B();
};

//队列的基本操作
SqQueue::SqQueue()
{
	head=last=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;
		last->next=p;
		last=p;
		p->next=NULL;
		return true;
	}
}
bool SqQueue::DeQueue(char &e)    //出队列
{
	if(head==NULL)
	{
		cout<<"Queue is empty"<<endl;
		return false;
	}
	else
	{
		Node *p=head;
		head=head->next;
		e=p->word;
		delete p;
		return true;
	}
}

void SqQueue::OutQueue()    //输出队列中的数据
{
	for(Node *p=head->next;p!=NULL;p=p->next)
		cout<<p->word;
	cout<<endl;
}

bool SqQueue::QueueEmpty()
{
	return head==last;
}

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;
	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);      
				S1.pop(e);
			} 
			while(!S3.StackEmpty())
			{
				S2.push(e1);    //根据第二种解释规则,将θ进行多次压栈操作
				S3.pop(e);
				S2.push(e);
			}
			S2.push(e1);
		}
	}
}


int main(void)
{
	char e;
	bool flag;
	SqStack S,S1,S2;
	SqQueue Q;
	SqStack();
	SqQueue();
	flag=read_language(S);     //读入魔王语言
	if(!flag)
	{
		cout<<"括号不匹配,无法解释!"<<endl;
		system("pause");
		return 0;
	}
	while(!S.StackEmpty())
	{
		S.pop(e);
		if(e==')')
		{
			S1.push(e);
			S2.pop(e);
			while(e!='(')
			{
				S1.push(e);
				S2.pop(e);
			}
			if(e=='(')
				S1.push(e);
			push_and_pop(S1,S2);
		}
		else
			S2.push(e);
	}
   //魔王语言的前面部分在栈S2的底部,后面部分在栈S2的顶部,需要转换一下
	while(!S2.StackEmpty())
	{
		S2.pop(e);
		S.push(e);    //魔王语言的后面部分在栈S的底部,前面部分在栈S的顶部
	}

	//上面的操作进行的是第二种解释规则
	//下面的操作进行的是第一种解释规则
	while(!S.StackEmpty())
	{
		S.pop(e);
		if(e=='A')
			Q.EnQueue_A();
		if(e=='B')
			Q.EnQueue_B();
		else
			Q.EnQueue(e);
	}
	cout<<"魔王语言可以解释为:"<<endl;
	Q.OutQueue();
	system("pause");
	return 0;
}


运行结果如下:

一重括号:


多重括号:

括号不匹配:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值