课程设计实践报告.docx

上传人:b****6 文档编号:8626927 上传时间:2023-02-01 格式:DOCX 页数:39 大小:934.55KB
下载 相关 举报
课程设计实践报告.docx_第1页
第1页 / 共39页
课程设计实践报告.docx_第2页
第2页 / 共39页
课程设计实践报告.docx_第3页
第3页 / 共39页
课程设计实践报告.docx_第4页
第4页 / 共39页
课程设计实践报告.docx_第5页
第5页 / 共39页
点击查看更多>>
下载资源
资源描述

课程设计实践报告.docx

《课程设计实践报告.docx》由会员分享,可在线阅读,更多相关《课程设计实践报告.docx(39页珍藏版)》请在冰豆网上搜索。

课程设计实践报告.docx

课程设计实践报告

北京工商大学

课程设计实践报告

 

学院:

计算机与信息工程学院

课程名称:

算法与数据结构

任课教师:

叶红

班级:

工科092

学号:

姓名:

同组学生:

实践地点:

北京工商大学良乡校区工二楼406

实践时间:

2011年1月3日至2011年1月7日

1、课程设计题目内容:

对一批汽车牌照进行排序和查找

排序和查找是在数据信息处理中使用频度极高的操作。

为加快查找的速度需先对数据记录按关键字排序,在汽车数据的信息模型中,汽车牌照是关键字,而且是具有结构特点的一类关键字。

因为汽车牌照号是数字和字母混编的,例如01B7328,这种记录集合是一个适于利用多关键字进行排序的典型例子,故我们可以利用链式基数排序方法实现排序。

在排序基础上,利用二分查找的思想,实现对这批汽车记录按关键字的查找。

2、设计要求

基本要求:

利用链式基数排序和二分查找的思想完成程序设计任务。

3、设计内容

(1)需求分析

程序的功能:

主要功能是对含有关键字的批量数据进行排序和查找;另外根据实际增添了输出到文件、删除、插入、简单统计功能。

输入输出的要求:

程序会显示提示,根据提示输入数字、字符或数据。

测试数据:

测试数据的每个记录包括五项,分别为牌照号码、汽车商标、颜色、注册日期和车主的姓名,其中牌照号码为七位(k0-k6),输入形式如下:

K0和k1输入值为01-04(代表地区),k2输入值为A~Z(代表车的使用类型),后4位为0000~9999(代表车号),例如:

O1B7328。

其余四项输入内容因为不涉及本程序的核心思想,故只要求一般字符串类型即可。

查询时,输入合法的汽车牌照号码。

测试数据要求用30个左右的数据项进行测试,头两位暂限定01~04,第3位为A~Z,以便可使牌照号码相对集中。

程序测试数据:

30

01S5842将明2007-12-02bluejid

04D2154陈琳2005-11-01yellowjo

02A0021潘晓静2011-04-22whitejae

01S8930李峰2010-08-13greenaie

03C3589张三2007-02-18bluenhi

04E2184Lucy2009-11-28blackas6

04A2505赵晗2009-10-30brownja

03C3269Lily2007-11-30pinkjos

03B3568Tom2005-12-17bluejos

01A8983Jim2006-02-19whitekfe

02A7777韩梦龙2005-02-07blackvds

02C2222钱国正2009-08-05greenyer

01G8652刘晓莉2008-11-07whitekfe

03H0029Kasserine2008-04-08blackxfd

04G9665索海丰2009-04-09redtrs

03B3222唐如云2007-10-08brownhtr

02L6622王睫2007-11-08bluenrr

04L1122Shelly2006-11-03blackgf

04A2200David2009-02-22redert

01E8000赵远2007-03-08pinktre

02V0009唐文2006-07-02bluethh

01B3321郑华2008-12-02whitejh

03S6699索耀光2008-01-01whiterd

03D4115赵沙2007-11-11yellowkew

01F6339赵欢欢2007-07-14redkfe

02H7775叶丽娜2009-08-15brownwg

02A8993孙珍珍2010-11-27whitewb

02P8692赵楠2006-10-12blacktrt

04W5524孙中华2004-03-21yellowms

03W6688John2007-01-11pinkesg

(2)概要设计

本程序所用的抽象数据类型的定义:

ArrType//指针数组类型

SLList//静态链表类型

SLCell//静态链表的结点类型

KeysType//定义关键字类型为字符型

InfoType//定义其它数据项的类型

主程序的流程及各程序模块之间的层次关系:

开始先选择读入原始数据方式:

1:

从文件读入(在桌面建立test.txt文档,第一行为记录数,记录数<=10000,记录数必须符实,否则程序出错;第二行开始数据,数据用空格隔开,例如:

01S5842将明2007-12-02bluejid);

2:

直接用程序内数据。

然后对数据进行操作:

1:

按车牌号排序并输出;

是否输出到文件?

(y/n)

2:

查找;

1):

按车牌号查找(排序后进行);

0:

退出1:

删除

2):

按车牌号前两位查找;

3):

按车牌号第三位查找。

3:

按顺序插入数据;(排序后)

4:

简单统计。

1):

按车牌号前两位统计;

2):

按车牌号第三位统计。

(3)详细设计

采用C语言定义相关的数据类型:

typedefstructInfoType//车主姓名等其它信息

{

charname[17];

chardate[12];

charcolor[11];

charmark[10];

}InfoType;//定义其它数据项的类型

typedefcharKeysType;//定义关键字类型为字符型

typedefstructSLCell//静态链表的结点类型

{

KeysTypekeys[MAX_NUM_OF_KEY+1];//关键字(字符串末尾+'\0')

InfoTypeoth;//其它数据项

intnext;

}SLCell;

typedefstructSLList//静态链表类型

{

SLCellr[MAX_SPACE];/*静态链表的可利用空间,r[0]为头结点*/

intkeynum;//记录的当前关键字个数

intrecnum;//静态链表的当前长度

}SLList;

typedefintArrType[RADIX];//指针数组类型

各模块的算法:

①基数排序:

voidDistribute(SLCellr[],inti,ArrTypef,ArrTypee);

/*静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。

本算法按第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。

f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录*/

voidCollect(SLCellr[],ArrTypef,ArrTypee);

/*本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成一个链表,e[0..RADIX-1]为各子表的尾指针。

*/

voidSort(SLListL,intadr[]);

/*求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号*/

voidRearrange(SLList&L,intadr[]);

/*adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。

本算法按adr重排L.r,使其有序。

*/

voidRadixSort(SLList&L);

/*L是采用静态链表表示的顺序表。

对L作基数排序,使得L成为按关键字自小到大的有序静态链表,L.r[0]为头结点。

*/

voidwrite(SLListl);//输出到文件

②查找:

intjudge(chars[]);//判断车牌号是否合法

intSearch1(SLListST);/*在表ST中折半查找其关键字等于key的数据元素。

若找到,则打印该元素在表中的信息*/

voidDelete(SLList*l,intd);//删除l中第d个记录

voidSearch2(SLListl);//据车牌号前两位搜索

voidSearch3(SLListl);//据车牌号第三位搜索

③插入:

intRead(SLListl,SLCell*r);/*读取车牌号到r,若l中有此车牌号则读取失败*/

voidInsert(SLList*l);/*在l中按基数排序顺序插入车牌号及其他信息*/

④统计:

voidStatistic1(SLListl);//据车牌号前两位进行统计

voidStatistic2(SLListl);//据车牌号第三位进行统计

函数的调用关系图:

(4)调试分析

调试中遇到的问题及对问题的解决方法:

我在调试中遇到了许多问题,由于问题太多无法一一说明,这里只说一些编译无错误而程序无法正常运行,或者程序的执行结果与预想的不同,其它的大部分错误软件在编译时会有提示,就不说了。

1、出现如图1情况的,我碰到的有几种。

图1

1)scanf或fscanf语句中一定要用变量的地址,而不是变量本身。

这种错误在学习C语言时就强调过,但编程时还是得小心,我的程序在编了300多行时出现这个错误,费了好些时间才查找出来;

2)数组或其它变量定义空间不足。

例如在基数排序中,需要两个指针数组,大小与基数相同,如果小于基数的话,会出现图1所示的情况。

2、程序执行结果与预想结果不同,如图2和图3所示

图2

这里有一个经常不经意犯的小错误,就是经常把“==”写成“=”,上图中while(a==0);以下还有一例:

图4和图5中,if(c==’y’)。

图3

图4

图5

3、有三个问题我不知如何解决:

①图4和图5中,运行结果是打印完“是否输出到文件?

(y/n)”后直接回车打印“输入错误”,之间并没有让输入字符进行选择;②图5中程序中使用的是scanf函数而不是getch()函数,因为编译时会提示没有getch()此函数,应该如何做才能把它找出来?

③如图6、图7和图8所示,当进行选择时,若输入字母,则会进入死循环,而输入其它数字时则不会,我试了一下,当输入如!

@#等特殊字符时也会进入死循环,我暂时没能解决掉这个问题。

图6

图7

图8

暂时就这些问题了。

(5)使用说明及测试结果

程序开始后,先选择读入原始数据方式;

选择后,程序会先将数据按原来顺序打印出来;

然后程序显示主菜单,对数据进行操作;

1:

按车牌号排序并输出;

程序会先对原始数据以车牌号为关键字进行基数排序并输出;

输出后程序会提示是否输出到文件,进行选择;

若选择“y”,程序会将排好序的数据记录在桌面建立txt文档保存;若选择“n”,程序会继续回到主菜单。

2:

查找;

1):

按车牌号查找(排序后进行);

程序会要求输入要查找的车牌号,读入后对其合法性进行检验,若不合法(格式不正确),会要求重新输入;若合法,则查找。

查找到后,程序会打印出车牌号的位置及其相关信息,然后进行选择是否删除;若未查找到,则打印“未找到与此车牌号相关的信息”;

2):

按车牌号前两位查找;

程序读入前两位后,会依次将满足条件的车牌号及其它相关信息打印出来,并在最后统计有多少个记录满足条件;

3):

按车牌号第三位查找;

同前一个查找类似,程序找到满足条件的车牌号后会依次打印出车牌号及其相关信息,并在最后总和共有多少记录满足条件。

先说,4:

简单统计。

1):

按车牌号前两位统计;

程序会对已存在的记录以前两位进行统计,分别打印出各个种类有多少个;

2):

按车牌号第三位统计

程序会对已存在的记录以车牌号第三位进行统计,分别打印出各个种类有多少个。

3:

按顺序插入数据;(排序后)

程序会先要求输入要插入数据的车牌号,进行判断是否合法,不合法包括格式不正确和原始数据中已存在,程序会给出相应的提示,要求不合法的重新输入,然后要求输入车主姓名及其它相关信息,进行插入操作,成功后程序会提示插入成功并将所在位置打印出来;

最后可以选择主菜单中的排序进行查看插入的数据及其所在位置。

完成操作后,想退出程序的可以通过主菜单中的“0:

退出”实现,其它菜单中一样可以通过此功能退出当前菜单。

(6)源程序(带注释)

这是我从cpp文件中直接复制粘贴过来的:

#include

#include

#include

#include

#include

#defineN30

#defineRADIX26/*关键字基数,此时是二十六个字母(包括十进制整数)的基数*/

#defineMAX_SPACE10000//链表最大空间

#defineMAX_NUM_OF_KEY7//关键字位数

typedefstructInfoType//车主姓名等其它信息

{

charname[17];

chardate[12];

charcolor[11];

charmark[10];

}InfoType;//定义其它数据项的类型

typedefcharKeysType;//定义关键字类型为字符型

typedefstructSLCell//静态链表的结点类型

{

KeysTypekeys[MAX_NUM_OF_KEY+1];//关键字(字符串末尾+'\0')

InfoTypeoth;//其它数据项

intnext;

}SLCell;

typedefstructSLList//静态链表类型

{

SLCellr[MAX_SPACE];/*静态链表的可利用空间,r[0]为头结点*/

intkeynum;//记录的当前关键字个数

intrecnum;//静态链表的当前长度

}SLList;

typedefintArrType[RADIX];//指针数组类型

intmenu0();//选择读入原始数据方式

intmenu();//总菜单

intmenu1();//查找菜单

intmenu11();//删除菜单

intmenu2();//统计菜单

intduru(SLList*l,intr);//执行读入原始数据

voidprint(SLListL,intw);//按数组序号输出静态链表

voidwrite(SLListl);//输出到文件

voidDistribute(SLCellr[],inti,ArrTypef,ArrTypee);

/*静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。

本算法按第i个关键字keys[i]

建立RADIX个子表,使同一子表中记录的keys[i]相同。

f[0..RADIX-1]和e[0..RADIX-1]分别指

向各子表中第一个和最后一个记录*/

voidCollect(SLCellr[],ArrTypef,ArrTypee);

/*本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成一个链表,e[0..RADIX-1]为各子表的尾指针。

*/

voidSort(SLListL,intadr[]);

/*求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号*/

voidRearrange(SLList&L,intadr[]);

/*adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。

本算法按adr重排L.r,使其有序。

*/

voidRadixSort(SLList&L);

/*L是采用静态链表表示的顺序表。

对L作基数排序,使得L成为按关键字自小到大的有序静态链表,L.r[0]为头结点。

*/

intjudge(chars[]);//判断车牌号是否合法

intSearch1(SLListST);/*在表ST中折半查找其关键字等于key的数据元素。

若找到,则打印该元素在表中的信息*/

voidSearch2(SLListl);//据车牌号前两位搜索

voidSearch3(SLListl);//据车牌号第三位搜索

voidStatistic1(SLListl);//据车牌号前两位进行统计

voidStatistic2(SLListl);//据车牌号第三位进行统计

voidDelete(SLList*l,intd);//删除l中第d个记录

intRead(SLListl,SLCell*r);/*读取车牌号到r,若l中有此车牌号则读取失败*/

voidInsert(SLList*l);/*在l中按基数排序顺序插入车牌号及其他信息*/

intmain()

{

SLListl;

inta,o,x,y,z;

l.recnum=N;

l.keynum=MAX_NUM_OF_KEY;

do

{

a=menu0();

a=duru(&l,a);

}while(a==0);

printf("车牌号排序前:

\n");

print(l,0);

do

{

x=menu();

switch(x)

{

case1:

RadixSort(l);

printf("车牌号排序后:

\n");

print(l,0);

write(l);

break;

case2:

do

{

y=menu1();

switch(y)

{

case1:

o=Search1(l);

if(o)

Delete(&l,o);

break;

case2:

Search2(l);break;

case3:

Search3(l);break;

case0:

break;

}

}while(y!

=0);

break;

case3:

if(l.recnum

{

Insert(&l);

break;

}

else

printf("空间已满,无法插入!

\n");

break;

case4:

do

{

z=menu2();

switch(z)

{

case1:

Statistic1(l);break;

case2:

Statistic2(l);break;

case0:

break;

}

}while(z!

=0);

break;

case0:

printf("\n\t\t\tByebye!

\n\n\n");

break;

}

}while(x!

=0);

system("pause");

return0;

}

intmenu0()

{

intx;

printf("-----------------------------------------------------------\n");

printf("|1:

从文件读入(在桌面建立test.txt文档,第一行为记录数,|\n");

printf("|记录数<=10000,记录数必须符实,否则程序出错;第二行|\n");

printf("|开始数据,数据用空格隔开,例如:

|\n");

printf("|01S5842将明2007-12-02bluejid);|\n");

printf("|2:

直接用程序内数据。

|\n");

printf("-----------------------------------------------------------\n");

printf("pleaseselect(1-2):

");

scanf("%d",&x);

while(x<1||x>2)

{

printf("输入错误!

\n");

printf("Pleaseenterthenumber(1--2):

");

scanf("%d",&x);

};

returnx;

}

intmenu()

{

intx;

printf("-----------------------------\n");

printf("|0:

退出!

|\n");

printf("|1:

按车牌号排序并输出;|\n");

printf("|2:

查找;|\n");

printf("|3:

按顺序插入数据;(排序后)|\n");

printf("|4:

简单统计。

|\n");

printf("-----------------------------\n");

printf("pleaseselect(0-4):

");

scanf("%d",&x);//怎样能避免输入两个数字和字母的情况?

while(x<0||x>4)

{

printf("输入错误!

\n");

printf("Pleaseenterthenumber(0--4):

");

scanf("%d",&x);

};

returnx;

}

intmenu1()

{

intx;

printf("------------------------------\n");

printf("|0:

退出!

|\n");

printf("|1:

按车牌号查找(排序后进行);|\n");

printf("|2:

按车牌号前两位查找;|\n");

printf("|3:

按车牌号第三位查找。

|\n");

printf("------------------------------\n");

printf("pleaseselect(0-3):

");

scanf("%d",&x);

while(x<0||x>3)

{

printf("输入错误!

\n");

printf("Pleaseenterthenumber(0--3):

");

scanf("%d",&x);

};

returnx;

}

intmenu11()

{

intx;

printf("------------------------------------\n");

printf("|0:

退出

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1