数据结构课程设计回文数问题.docx
《数据结构课程设计回文数问题.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计回文数问题.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构课程设计回文数问题
湖南科技学院
课程设计报告
课程名称:
数据结构课程设计
课程设计题目:
02、回文问题
系:
专业:
年级、班:
姓名:
学号:
指导教师:
职称:
2011年12月
1.问题描述----------------------------------------------------------------------3
2.具体要求----------------------------------------------------------------------3
3.测试数据----------------------------------------------------------------------3
4.算法思想----------------------------------------------------------------------3
5.模块划分----------------------------------------------------------------------4
6.数据结构----------------------------------------------------------------------4
7.源程序------------------------------------------------------------------------7
8.测试情况--------------------------------------------------------------------14
9.设计总结--------------------------------------------------------------------14
10.参考文献--------------------------------------------------------------------15
一、问题描述
利用栈跟队列找出一个TXT文档中所有的回文单词并输出。
回文单词就是单词中字母从前往后拼与从后往前拼得出的单词是一样的,如:
AaA、121、1221、d、did等,从数据结构角度看,栈和队列是特殊的线性表,其特殊性在于栈和队列的基本操作是线性表操作的子集,它们是操作受限的线性表,而栈是一种限定仅在表尾进行插入或删除的线性表,栈的修改是按先进后出的顺序进行的,队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端进行删除,因此可利用栈和队列的这两个性质对一个单词是否为回文单词进行检测,如果是则输出这个单词即可。
一句话里可能既包含字母、数字还可能包含标点符号,回文单词的判断是不包含标点符号的,但文件输入流读取的时候标点也被一起读取进来了,因此要删除紧跟单词后中的标点符号,单独对各个单词进行判断。
二、具体要求
此课程设计要求编写程序以实现检测出文档中的回文单词并将其输出的功能,首先要将每一个单词从文档读取出来,其次对每一个单词进行回文判断,主程序用栈和队列实现,以进一步巩固、理解和熟练掌握栈和队列的基本操作;同时对文本文件进行读取数据要利用到文件输入流的知识。
三、测试数据
用文本文档data.txt,进行测试,输出回文数,及个数。
文本文档中除英文字母,数字,常见标点符号外无其他字符,并且编码采用常见的ANSI编码。
四、算法思路
1、初始化栈和队列,读入TXT文本文档,若文档不能正常读入,则输出文档读入错误,若正常读入,文档非空则将文档中的单词逐个读入到字符串中。
2、因为标点符号都是紧跟单词后的,故对每个字符串首先得判断最后一个字符c,若c既不是字母也不是数字,字符串的长度减一,即以标点符号结束的字符串最后一个字符不压入栈跟队列,不参与回文单词的判断。
3、调用出栈与出队列函数,逐个比较出栈与出队列字符是否一样,用count记录栈中出来的与队列出来的相同字符的个数,若count==str.length()则说明该字符串从栈中出来跟从队列出来完全一样,即字符串完全对称,为回文单词,输出,回文单词加一个,否则什么也不做。
4、读取至文本文档最后时,程序结束,关闭文本文档,同时销毁队列。
5、假设文本文档中除英文字母,数字,常见标点符号外无其他字符,并且编码采用常见的ANSI编码。
五、模块划分
函数功能:
voidinitStack(SqStack&s);//构造一个空栈s
voidclearStack(SqStack&s);//清空栈
boolisEmpty(SqStack&s);//判断栈是否为空
boolisFull(SqStack&s);//判断栈是否满
voidpush(SqStack&s,constchar&e);//插入元素e为s的新的栈顶元素(进栈)
charpop(SqStack&s);//若栈不空,则删除s的栈顶元素(出栈)
voidinitQueue(LinkQueue&q);//构造一个空队列q
boolisEmpty(LinkQueueq);//判断队列是否为空
voiddestroyQueue(LinkQueue&q);//销毁队列
voidinsertElem(LinkQueue&q,chare);//插入元素e为q的新的队尾元素(进队列)
chardeleteElem(LinkQueue&q);//若队列不空,则删除q的对头元素(出队列)
六、数据结构
定义栈:
structSqStack//定义栈
{
charbase[MAXSIZE];
inttop;
};
定义队列:
structQNode//定义队列结点
{
chardata;
QNode*next;
};
structLinkQueue//定义队列
{
QNode*front;
QNode*rear;
};
图示:
栈
图示:
队列,插入元素
抽象数据类型栈定义如下
ADTstack
{
数据对象:
D={
|
i=1,2,……,n,n
0}
数据关系:
R1={<
>|
D,i=2,……n};
约定
端为栈顶,
端为栈底
基本操作:
InitStack(&s)
操作结果:
构造一个空栈
clearStack(&s)
初始条件:
栈s存在
操作结果:
将栈s清空为空栈
isEmpty(&s)
初始条件:
栈s存在
操作结果:
判断栈是否为空,为空返回true,否则返回false;
isFull(&s)
初始条件:
栈s存在
操作结果:
判断栈是否满,满返回true,否则返回false;
push(&s,e)
初始条件:
栈s存在
操作结果:
插入元素e作为新的栈顶元素
pop(&s,&e)
初始条件:
栈s存在
操作结果:
删除栈s的栈顶元素,并用e返回其值
}
ADTstack
{
数据对象:
D={
|
i=1,2,……,n,n
0}
数据关系:
R1={<
>|
D,i=2,……n};
约定
端为队列尾,
端为队列头
基本操作:
initQueue(&q);
操作结果:
构造一个空队列q
isEmpty(q)
初始条件:
队列q存在
操作结果:
判断队列是否为空,为空返回true,否则返回false
destroyQueue(&q)
初始条件:
队列q存在
操作结果:
销毁队列q
insertElem(&q,e)
初始条件:
队列q存在
操作结果:
插入元素e为q的新的队尾元素
deleteElem(&q)
初始条件:
队列q存在
操作结果:
若队列不空,则删除q的对头元素
}
新定义数据类型:
MAXSIZE数据类型int
七、源程序
Sqstack.h
#ifndefSQSTACK_H_INCLUDED
#defineSQSTACK_H_INCLUDED
constintMAXSIZE=150;
structSqStack//定义栈
{
charbase[MAXSIZE];
inttop;
};
voidinitStack(SqStack&s);//构造一个空栈s
voidclearStack(SqStack&s);//清空栈
boolisEmpty(SqStack&s);//判断栈是否为空
boolisFull(SqStack&s);//判断栈是否满
voidpush(SqStack&s,constchar&e);//插入元素e为s的新的栈顶元素(进栈)
charpop(SqStack&s);//若栈不空,则删除s的栈顶元素(出栈)
#endif//SQSTACK_H_INCLUDED
SqStack.h
#include
#include
#include
#include"SqStack.h"
usingnamespacestd;
voidinitStack(SqStack&s)//构造一个空栈s
{
s.top=0;
}
voidclearStack(SqStack&s)
{
s.top=0;
}
boolisEmpty(SqStack&s)
{
return(s.top==0);
}
boolisFull(SqStack&s)
{
return(s.top==MAXSIZE);
}
voidpush(SqStack&s,constchar&e)//插入元素e为s的新的栈顶元素(进栈)
{
if(s.top==MAXSIZE)
{
cerr<<"Stackoverflow!
"<exit
(1);
}
s.base[s.top]=e;
++s.top;
}
charpop(SqStack&s)//若栈不空,则删除s的栈顶元素(出栈)
{
if(s.top==0)
{
cerr<<"Stackisempty!
"<exit
(1);
}
--s.top;
chartemp=s.base[s.top];
returntemp;
}
LinkQueue.h
#ifndefLINKQUEUE_H_INCLUDED
#defineLINKQUEUE_H_INCLUDED
structQNode//定义队列结点
{
chardata;
QNode*next;
};
structLinkQueue//定义队列
{
QNode*front;
QNode*rear;
};
voidinitQueue(LinkQueue&q);//构造一个空队列q
boolisEmpty(LinkQueueq);//判断队列是否为空
voiddestroyQueue(LinkQueue&q);//销毁队列
voidinsertElem(LinkQueue&q,chare);//插入元素e为q的新的队尾元素(进队列)
chardeleteElem(LinkQueue&q);//如队列不空,则删除q的对头元素(出队列)
#endif//LINKQUEUE_H_INCLUDED
LinkQueue.cpp
#include
#include
#include
#include"LinkQueue.h"
usingnamespacestd;
voidinitQueue(LinkQueue&q)//构造一个空队列q
{
q.front=q.rear=newQNode;
if(!
q.front)
exit
(1);
q.front->next=NULL;
}
voiddestroyQueue(LinkQueue&q)
{
while(q.front)
{
q.rear=q.front->next;
deleteq.front;
q.front=q.rear;
}
}
voidinsertElem(LinkQueue&q,chare)//插入元素e为q的新的队尾元素(进队列)
{
QNode*p=newQNode;
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
}
chardeleteElem(LinkQueue&q)//如队列不空,则删除q的对头元素(出队列)
{
if(q.front==q.rear)
{
cerr<<"Queueisempty!
"<exit
(1);
}
QNode*p=q.front->next;
chare=p->data;
q.front->next=p->next;
if(q.rear==p)//若队列中只剩一个元素
q.rear=q.front;//删除最后一个元素,链队为空,则需同时使队尾指针指向头结点
deletep;
returne;
}
boolisEmpty(LinkQueueq)
{
returnq.front==q.rear;
}
main.cpp
#include
#include
#include
#include
#include"SqStack.h"
#include"LinkQueue.h"
usingnamespacestd;
intmain()
{
stringstr;
inti,sum=0;
LinkQueueq;
SqStacks;
initStack(s);
if(isEmpty(s))
{
cout<<"栈初始化成功!
"<}
initQueue(q);
if(isEmpty(q));
{
cout<<"队列初始化成功!
"<}
ifstreaminfile("data.txt");
if(!
infile)cout<<"读入文本文件发生错误"<cout<<"**************文本文件中回文单词如下***************"<while(infile.eof()==0)
{
intcount=0;
infile>>str;
i=str.length();
charc=str[i-1];
if(c>='a'||c<='z'||c>='A'||c<='Z');
else
i--;
for(intj=0;j
{
push(s,str[j]);
insertElem(q,str[j]);
}
for(intk=0;k
if(pop(s)==deleteElem(q))
count++;
if(count==i&&infile.eof()==0)
{
for(intn=0;n
cout<cout<<"";
sum++;
}
}
infile.close();
cout<cout<<"此文本文档中共有回文单词:
"<cout<<"****************************************"<clearStack(s);
if(isEmpty(s))
{
cout<<"栈销毁成功!
"<}
destroyQueue(q);
if(isEmpty(q));
{
cout<<"队列销毁成功!
"<}
return0;
}
八、测试情况
测试结果分析
对于语句中的一般回文单词能正常输出,句末跟标点符号连在一起的回文单词也能通过程序把字符串末尾的标点给去掉并正常输出,而字符串中的连接符可以作为回文单词的组成部分一起输出。
九、设计总结
本次课程设计我本来打算做第一个的,后来还是不得不做第二个,但最后我还是将第一个和第二个一起做了,我觉得回文数检查太简单,所以也没有花多大功夫去做,只是利用了栈和队列的性质,将字符压入栈与队列中,然后压出,判断是否相等,相等就输出。
设计时本来想弄复杂点的,最后还是觉得没必要,既然简单的几行代码就能实现,何必去画蛇添足呢?
简单就行,于是简单的编了出来。
利用压栈和出栈判断有一个缺点,就是如果单词开头存在“”或者‘’时,无法进行判断,这样导致计算出来的结果不够准确。
在顺利的完成了设计,我明白了在编写程序的时候,应该尽量使界面简洁大方,布局统一。
变量类型的定义,程序可以设计的很简单,够用就好,这样程序就可以尽可能的减少对系统资源的占用。
当然这样在设计时也免不了存在着一些不足。
十、参考文献
1.谭浩强《C++程序设计》清华出版社
2.严蔚敏,吴伟民.数据结构.清华大学出版社,2007.4