数据结构之魔王语言

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

魔王语言
一、需求分析
1.问题描述
有一个魔王总是使用自已的一种非常精练而抽象的语言讲话,没有人能听得懂。

但他的语言是可以逐步解释成人能懂的语言的,因为他的语言是由以下两种形式的规则由人的语言逐步抽象上去的:(1)α→β1β2…βm
(2)(θβ1β2…βm)→(θβm…β2θβ1θ)
在这两种形式中,从左到右均表示解释。

写一个魔王解释程序,将魔王的话解释成人能听懂的话。

2.基本要求
用下述两种规则和下述规则(2)实现。

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

魔王语言可含人的词汇。

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

二、概要设计
利用C++的类模版,创建栈和队列的类模版,并实现其基本操作template <class T>
class Stack{
数据对象:D = { a i | a i∈char, i = 1,2,3……,n, n≥0}
数据关系:R 1 = { <a i-1,a i> | a i-1,a i∈D,i = 2,……n}
约定a n端为栈顶,a1端为栈底。

Stack() //栈的构造函数
~Stack() //栈的析构函数
Push(const T &x) //入栈
Pop(T &x) //出栈
Top(T &x) //取栈顶元素
IsEmpty() //判断栈是否为空
IsFull() //判断栈是否为满
Size() //求栈当前元素的个数}
Template<class T>;
class Queue
{
数据对象:D = { a i | a i∈char, i = 1,2,3……,n, n≥0} 数据关系:R 1 = { <a i-1,a i> | a i-1,a i∈D,i = 2,……n}
约定其中a1端为队列头,a n端为队列尾。

Queue ( ) //队列的构造函数
~Queue ( ) //队列的析构函数
EnQueue ( ) //进队
DeQueue ( ) //退队
GetFront ( ) //取队头元素
MakeEmpty ( ) //清空队列
IsEmpty ( ) //判断队列是否为空
IsFull ( ) //判断队列是否满
Length ( ) //求队列当前长度
};
主程序
int main()
{
cin 输入魔王语言并进行判断合理性queue,stack 进行站和队列的操作
switch 对输入的魔王语言进行转换并输出}
三、详细设计
const int stackIncreament=100;
template <class T>
class Stack{
public:
Stack(int sz=50);
~Stack() { delete[] elements; }
void Push(const T &x); // 入栈
bool Pop(T &x); //出栈
bool Top(T &x); //取栈顶元素
bool IsEmpty() const {return (top==-1)? true:false;}
bool IsFull() const {return (top==maxSize-1)? true:false;}
int Size() const {return top+1; }
private:
T * elements; //栈元素数组
int top; //栈顶
int maxSize; //最大元素个数
void overflowProcess();
};
template<class T>
Stack<T>::Stack(int sz):top(-1),maxSize(sz) { elements=new T[maxSize];
assert(elements!=NULL);
}
template<class T>
void Stack<T>::overflowProcess() {
T *newArray=new T[maxSize+stackIncreament];
assert(newArray!=NULL);
for(int i=0;i<=top;i++) newArray[i]=elements[i];
maxSize=maxSize+stackIncreament;
delete[] elements;
elements=newArray;
};
template <class T>
void Stack<T>::Push(const T& x)
{
if(IsFull()==true) overflowProcess();
elements[++top]=x;
}
template <class T>
bool Stack<T>::Pop(T &x)
{
if(IsEmpty()==true) return false;
x=elements[top];
top--;
return true;
}
template <class T>
bool Stack<T>::Top(T &x)
{
if(IsEmpty()==true) return false;
x=elements[top];
return true;
}
template<class T>
class Queue
{
private:
int rear, front; //队尾, 队头指针
T *elements; //队列元素数组
int maxSize; //最大元素个数public:
Queue ( int sz= 10 );
~Queue ( ) { delete [ ] elements; }
void EnQueue ( const T & item); //进队
bool DeQueue ( ); //退队
T GetFront ( ); //取队头元素
void MakeEmpty ( ) { front = rear = 0; }
int IsEmpty ( ) const
{ return front == rear; }
int IsFull ( ) const
{ return (rear+1) % maxSize == front; }
int Length ( ) const
{ return (rear-front+maxSize) % maxSize;}
};
template <class T>
Queue<T>:: Queue ( int sz ) :
front (0), rear (0), maxSize (sz) {
elements = new T[maxSize];
assert ( elements != NULL );
}
template <class T>
void Queue<T>::EnQueue ( const T & item ) { assert ( !IsFull ( ) );
rear = (rear+1) % maxSize;
elements[rear] = item;
}
template <class T>
bool Queue<T> :: DeQueue ( ) {
if ( IsEmpty ( ) ) return false;
front = ( front+1) % maxSize;
return true;
}
template <class T>
T Queue<T> :: GetFront ( ) {
assert ( !IsEmpty ( ) );
return elements[( front+1) % maxSize];
}
#include<iostream>
#include<assert.h>
#include"stack.h"
#include"queue.h"
using namespace std;
void lang_cin(char * a) //输入魔王语言,并判断输入正确性
{
bool choose=true;
cout<<"请输入魔王语言:"; //魔王语言中的大写字母用A和B来代替;
while(choose)
{
cin>>a;
int length=strlen(a);
int t=0;
while(t!=length)
{
if(!(a[t]!='t'||a[t]!='d'||a[t]!='s'||a[t]!='a'||a[t]!='e'||a[t]!='z'||a[t]!='g'||a [t]!='x'||a[t]!='n'||a[t]!='h'||a[t]!='A'||a[t]!='B'||a[t]!='('||a[t]!=')'))
{cout<<"请重新输入:";break;}
else t++;
}
if(t==length)
choose=false;
}
}
void lang_stack_queue(Stack<char> &s,Queue<char> &q,char * a) //对魔王语言进行栈和队列的处理
{
int length=strlen(a);
for(int i=length-1;i>=0;i--)
{
if(a[i]=='(')
{
char e,str; //e为删除或插入的字符,str为重复输入的字符
s.Pop(str);
while(1)
{
s.Pop(e);
if(e==')')
break;
q.EnQueue(e);
}
while(!q.IsEmpty())
{
s.Push(str);
e=q.GetFront();
q.DeQueue();
s.Push(e);
}
s.Push(str);
}
else
s.Push(a[i]);
}
}
void display(Stack<char> & s) //将栈中的魔王语言输出{
while(!s.IsEmpty())
{
char e;
s.Pop(e); //删除栈顶元素
switch(e)
{
case 't': cout<<"天";break;
case 'd': cout<<"地";break;
case 's': cout<<"上";break;
case 'a': cout<<"一只";break;
case 'e': cout<<"鹅";break;
case 'z': cout<<"追";break;
case 'g': cout<<"敢";break;
case 'x': cout<<"下";break;
case 'n': cout<<"蛋";break;
case 'h': cout<<"恨";break;
case 'A': cout<<"上一只鹅";break;
case 'B': cout<<"天上一只鹅地上一只鹅";break;
default: cout<<"ERROR!!!";
}
}
cout<<endl;
}
int main()
{
char * A="sae"; //A→sae
char * B="tsaedsae"; //B→tAdA
char lang[50]="A(tdsa)B"; //输入的魔王语言数组
Stack<char> sta(50);
Queue<char> q(50);
lang_cin(lang);
lang_stack_queue(sta,q,lang);
display(sta);
return 0;
}
四、调试分析
1、在判断从控制台窗口输入魔王语言是否符合题目要求时,由于
判断条件控制不当,导致程序总是提示重复输入;
2、在对魔王语言字符串进行解释时,把括号内的小写字母出栈入
队列后,然后从队列在入栈时,没有把需要重复输出的字符入
栈,导致输出时与要求不一样。

3、在进行Stack、Queue的类模版、几个函数的实现时,出现了一
些语法错误,比如没有打分号、拼写错误、数据类型不匹配等,经过调试后解决问题。

五、经验和体会
1、写完两个类模版之后,就开始写主函数,完成之后发现主函数
非常长,调试很麻烦。

然后意识到应该把主函数模块化,把需
要完成的几个功能分隔成几个函数,最后主函数看着非常精简,有利于程序的健壮性。

2、在对类模版惊醒实例化的时候一定要注意指定其数据类型,且
在其他的函数中也要与对象的数据类型个保持一致,否则会发
生灾难性错误。

3、通过这次魔王语言的课程设计,我熟练地认识到了栈和队列的
作用性,在处理某些问题时,灵活的对其运用,可以完美的达
到目的。

六、运行结果
本科生课程设计成绩评定表
班级:计算机0806姓名:拉巴珠久学号:0120710340401
注:优(90-100分)、良(80-89分)、中(70-79分)、及格(60-69分)、60分以下为不及格。

指导教师签名:。

相关文档
最新文档