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

来源:互联网 发布:淘宝退款诈骗 借贷 编辑:程序博客网 时间:2024/05/17 08:23

 [问题描述] 
有一个魔王总是使用自己的一种非常精练而又抽象的语言讲话,没有人能听得懂,但他的语言是可以逐步解释成人能听懂的语言,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的: 
(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中,重复这个过程,直至将魔王语言中所有的括号都处理完为止,所以这个思路可以处理多重括号嵌套的问题。。

完整的实现代码如下:

[cpp] view plain copy
  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. }  


运行结果如下:

一重括号:


多重括号:

括号不匹配:

0 0
原创粉丝点击