1、3编码实现和静态检查3天4上机准备和上机调试2天5总结和整理设计报告1天合 计7天指导教师签名: 2014年 06月25日 系主任(或责任教师)签名: 2014年06月25日1. 需求分析1.1 基本要求(1)所有原始数据一律事先用文本文件保存,读入数据时从文件获取。(2)航班价格可以用随机函数生成,但建议从网上直接复制真实数据。(3)可输出所有城市名称以及每一城市所有可直飞到达的城市列表。(4)可输出任一指定直飞线路(若没有则显示无直飞航班)四个季度的全票和折扣价格。(5)输入月份、起始城市和目的城市名称,程序能显示出最经济 的中转路线选择方案。1.2 输入 (1)从文件read.txt中读
2、取不同城市之间(共10个城市)不同航线(共24条航线)的最高价格输入,四个季度有相同的最高价格。 (2)每条线路每季度的折扣率由随机函数产生,范围是0.201.00(小数点后取两位),四个季度有不同的折扣。 (3)运行程序时需根据要求从键盘输入相应指令,保证程序的正确运行。1.3输出(1)输出所有城市名以及每一城市所有可直飞到达的城市列表(按城市名拼音升序排列):始发地 可直飞目的地北京 长春 广州 杭州 昆明 上海 首尔 武汉 香港首尔 北京 上海 台北 香港(2)输出指定线路四个季度的折扣和全价:输入:北京-台北输出:无直飞航班北京-广州季度 全票价格 折扣 折后价格(不计小数,四舍五入)
3、 1 1240 6.5 806 2 1192 7.0 834 3 1475 4.6 679 4 1230 8.7 1070(3)输入月份、起始城市和目的城市名称,输出最佳方案:5 北京-台北最佳线路:北京-香港,1503,香港-台北,791,合计22947 广州-首尔广州-上海,880,上海-首尔,773,合计165310 武汉-上海武汉-上海,278,合计2781.4测试数据文本文件read.txt内容:(1)读文本文件read.txt。若文件名输入正确且文件无错误,则显示主菜单。若文件名输入错误或文件有错误,则显示“打开输入文件出错”。(2)根据主菜单提示选择需要执行的功能。若输入功能序号
4、在04之间,则执行相应的功能。若输入功能序号不在04之间,则显示“出错啦!请在0-4之间选择!”和主菜单,需重新选择。(3)选择1,输出城市列表及相应代码。(4)选择2,输出所有城市名以及每一城市所有可直飞到达的城市列表(按城市名拼音升序排列)。(5)选择3,先显示城市列表及相应代码,方便后面的输入操作,根据提示“请输入起始城市和目的城市的代码,中间以空格隔开,范围(1- 10)”输入两个城市代码,若两城市间有直飞航班则显示指定线路四个季度的折扣和全价。若两城市间无直飞航班则显示“无直飞航班”。(6)选择4,显示“请输入月份(请在1-12之间选择):”若月份输入正确,则先显示城市列表及相应代码
5、,方便后面的输入操作,根据提示“请输入起始城市和目的城市的代码,中间以空格隔开,范围(1- 10)”输入两个城市代码,若代码输入正确,则显示最佳方案。若月份输入错误,则显示“输入出错”。若城市代码输入错误,则显示“出错啦!”。(7)选择0,则直接退出程序。(8)在每一个功能执行完后,都会提示继续执行还是返回主菜单。箭头流程武汉北京长沙厦门上海郑州广州深圳天津大连15841219261110067431573612113014611903234615751.5无向带权费用图2. 概要设计2.1 抽象数据类型定义本程序运用了关于图这种数据结构,它的抽象数据类型定义如下:typedef struct
6、 unDiGraph int numVerts; /结点 costAdj cost; /邻接矩阵unDiGraph,*UNG;基本操作:unDiGraph* CreateCostG()操作结果:构造带权(费用)图。PathMat *Floyed(unDiGraph *D) 操作结果:Floyed函数 求任意两点的最短路径。2.2 主程序流程及各程序模块之间的层次(调用)关系 Main函数 输出方式1 f_money1()pri() 查看城市 输出方式3 f_money3() 输出方式2 f_money2()退出程序 pr(i,0) Floyed() Floyed() pr(Bcity,0) p
7、r(Bcity,0) prn_pass(Bcity,Ecity) prn_pass(Bcity,Ecity) pr(Ecity,0) pr(Ecity,0)3. 详细设计3.1 数据类型(1)主界面包括1.查看城市 2.输出所有城市名及所有可直飞到达的城市列表(按城市名拼音升序排列) 3.输入起始城市和目的城市名称,输出指定线路四个季度的折扣和全价 4.输入月份、起始城市和目的城市名称,输出最佳方案 0.退出程序(2)程序的模块为#include stdlib.htime.h /需引用的头文件#define INF 65535 /定义一个最大数为无穷值,表示两城市之间无直飞航班#define
8、MAX 23typedef int costAdjMAX+1MAX+1;/图邻接矩阵从1开始记数int PathMAX+1MAX+1; /图的定义costAdj B,L;void pr(int i)/选择城市void pri()/输出城市unDiGraph *CreateCostG()/构造带权(费用)图 返回首地址G:void Floyed(unDiGraph *D,unDiGraph *M) /Floyed函数 求任意两点的最短路径:void prn_pass(int i,int j) /为了求从i到j的最短路径,只需要调用如下的过程void f_money1()/输出所有城市名及所有可直
9、飞到达的城市列表(按城市名拼音升序排列)void f_money2()/输入起始城市和目的城市名称,输出指定线路四个季度的折扣和全价 void f_money4()/输入月份、起始城市和目的城市名称,输出最佳方案int LineNumStat(FILE *fp)/统计文本文件的行数void main()/main函数3.2 伪码算法(1)pr() 选择城市begin0=hIf j=0 then h=iElse if j=1 input addi.aSwitch 条件选择 print 城市名End(2)pri() 输出城市Print 城市代码1=iWhile ib,1=Wuhan10,Beiji
10、ng10,Xiamen10,Guangzhou10,Dalian10, Shanghai10,Changsha10,Shenzhen10,Zhengzhou10,Tianjin10G=(unDiGraph *)malloc(sizeof(unDiGraph)If !G then NULLc_number+1 While j G-costij 初始化使G-costij为无穷。c_number =G-numVerts while(!feof(fp) fscanf fp,%f %f %f %f %f %f %f %f %f %f,&Wuhani,&Beijingi,&Xiameni,&Guangzh
11、oui,&Daliani, &Shanghaii,&Changshai,&Shenzheni,&Zhengzhoui,&Tianjini for(0=j;jcostj1 Beijingj-1=costj2 Xiamenj-1=costj3 Guangzhouj-1=costj4 Dalianj-1=costj5 Shanghaij-1=costj6 Changshaj-1=costj7 Shenzhenj-1=costj8 Zhengzhouj-1=costj9 Tianjinj-1=costj10 return(G);(4) Floyed(unDiGraph *D,unDiGraph *M)
12、 函数 Floyed函数求任意两点的最短路径c_number=nwhile(ijwhile(jcostij=Aij 初始化矩阵A。 M-Cij -1=Pathij 初始化矩阵p, 置-1. for(0=k;k=n;k+) 为逐步加入的中间结点 i;i if(Aik+AkjAij K= Pathij 若i经过k到j比i到j小,则令 Aij=Aik+Akj Aij=Bij elseBij print最短路径为:(5)prn_pass(int i,int j) 输出最短路径所经过的点Begin If ( Pathij!=-1)递归调用prn_pass(i,Pathij)调用pr(Pathij,0)(
13、6)f_money1( ) 输出方式1函数 Begin ldo Print 始发地 可直飞目的地 Print 北京 广州 武汉 Print 长沙 大连 天津 Print 大连 长沙 厦门 郑州 Print 广州 北京 上海 郑州 Print 上海 广州 深圳 天津 Print 深圳 上海 天津 Print 天津 长沙 上海 深圳 Print 武汉 北京 厦门 Print 厦门 大连 武汉 Print 郑州 长沙 广州 Print 1.继续输出所有城市名以及每一城市所有可直飞到达的城市列表 2.返回主菜单 清选择. input l 输入1或2选择是否继续。 1=(7) f_money2( ) 输
14、出方式2函数Bcity,Ecity/起始成市号码和终点城市号码 money4 i,j s,wdiscount4while(h=1) print请输入起始城市和目的城市的代码,中间以空格隔开,范围(1- %d,c_numberinput Bcityinput Ecity 输入起始城市和终点城市的代码。 if (!(0Bcity&Bcityc_number+1)&(0Ecity&Ecity5000|LBcityEcity10000) then print无直飞航班 else Print季度 全票价格 折扣 折后价格(不计小数,四舍五入)n srand(unsigned)time(NULL)随机种子
15、 for (0=4; i w w/100=s break; s=discountj i+) (floatdiscounti*BBcityEcity= moneyiPrint %d %d %.2lf %.lfn,i+1,BBcityEcity,discounti,moneyi); Print“打折前的费用是%d元n,LBcityEcity Print 1.继续输入起始城市和目的城市名称,输出指定线路四个季度的折扣和全价n 2.返回主菜单n 清选择.(8) f_money3( ) 输出方式3函数Bcity,Ecity起始成市号码和终点城市号码 L money M month quarterdo P
16、rint请输入月份(请在1-12之间选择): Input month if(month=12|month5000) print无航班n else srand(unsigned)time(NULL随机种子 if(1=monthm 1=quarter Print你选择的是%d月,位于第%d季度,折扣是%.2lfn,month,quarter,m else if(4 2= else if(7 3= else if (10 4= (float)m*BBcityEcity=money 最佳线路: 合计: %.lfn,money Print 1.继续输入月份、起始城市和目的城市名称,输出最佳方案n 2.返
17、回主菜单n 清选择.4. 调试分析4.1 问题与解决办法(1)声明变量语句的位置我在运行的过程中一直出现这个错误(见下图),系统报错说未定义变量,但我确实定义过了,后来通过在网上XX资料才知道要把声明变量的语句得放到函数的最前面,而printf要放在所有变量声明语句后面。修改程序之后,那些错误果然没有了。(2)文本文件的读取 程序在读取文本文件时总说打开文件出错,原因是read.txt中含有非法字符,删去即可。而且在程序末尾要记得调用函数fclose(),关闭文件。(3)把从文本文件读取的数据保存到数组中编写这一部分的时候总是出现错误,主要是对指向数组的指针认识不清,通过这次编程对它有了更深的
18、了解。(4)scanf(%saddi.a) 和 printf(%s ,addi-10.a)在编写程序阶段,我最开始编写这两个函数的时候是scanf(%caddi.a) printf(%c ,addi-10.a) ,当时没有看清addi.a最初的定义,它其实是一个字符数组,所以在运行的时候老出错,后面慢慢研究和调试才知道在输入和输出的格式占位符应该用%s.(5)随机函数的编写我以前几乎没接触过随机函数,所以对其不是很了解。刚开始的时候都不会写,后来在网上找实例,才知道其用法。而且根据题目的要求产生折扣的范围是0.201.0(小数点后取两位),所以要产生有小数范围的不同随机数,就要用时间作为产生随
19、机数的种子,并且通过取余运算和除以整数100来确定随机数的范围。另外还需引用以下头文件:# include 4.2 算法的时空分析(1)时间复杂度: Floyed函数T(n)=O(n2+n3)(2)空间复杂度:本程序的空间复杂度均为S(n)=(n2); 即存放n2个节点数据辅助空间。4.3 经验和体会(1)c语言的学习实践很重要。自学习C语言以来,我们就没怎么练习上机实践能力,所以对于代码的敏感度不够,一个错误出现了,不是很容易发现。在这次课程设计中,我就犯了很多高手认为很基础的错误,比如说:printf函数的用法,变量声明的位置,还有就是指针数组的用法。犯错误是不可避免的,但是我们要认真地去发现错误和修改错误。我在运行后,知道自己的程序有错误,我首先一步一步慢慢看,慢慢分析,在整个程序中找不出来就将该部分分离出去进行测试,这样,就很容易找到问题所在了。(2)编写c语言程序必须要细心,特别注意标点符号的书写。同一个error可能要改个几遍才能改好,由于平时编程经历少的缘故,总感觉有些吃力,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1