数据结构课程设计 -万年历
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学生实验报告
实验课名称:数据结构
实验项目名称:万年历
专业名称:计算机科学与技术
班级:44444444444444
学号:4444444444444
学生姓名:古古怪怪
教师姓名:坎坎坷坷
2009年 6 月28 日
一、实验名称:万年历
二、实验目的与要求
设计目的
1、数据结构是计算机专业的教学计划中的核心课程之一,数据结构在计算机科学中是一门综合性的专业基础课。
“数据结构”的研究不仅涉及到计算机硬件(特别是编码理论、存储装置和存取方法等)的研究范围,而且和计算机软件的研究有着更密切的关系,无论是编译程序还是操作系统,都涉及到数据元素在存储器中的分配问题。
在研究信息检索时也必须考虑如何组织数据,以便查找和存取数据元素更为方便。
因此,可以认为“数据结构”是介于数学、计算机硬件和计算机软件三者之间的一门核心课程。
在计算机科学中,“数据结构”不仅是一般程序设计(特别是非数值计算的程序设计)的基础,而且是设计和实现编译程序、操作系统、数据库系统及其他系统程序和大型应用程序的重要基础。
2、通过本项课程设计,可以培养独立思考、综合运用所学有关相应知识的能力,能更好的巩固《数据结构》课程学习的内容,掌握工程软件设计的基本方法,强化上机动手编程能力,闯过理论与实践相结合的难关!更加了解了c语言的好处和其可用性!同时增加了同学之间的团队合作精神!更加也体会到以后在工作中团队合作的重要性和必要性!
3、通过数据结构课程设计,使学生了解高级程序设计语言的结构,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。
为后续各门计算机课程的学习和毕业设计打下坚实基础。
设计要求
1、能够显示星期;
2、能够显示年月日;
3、能显示十二个月;
4、能准确显示阳历的每一天;
4、格式与日历一致;
二、实验内容:
1、输出公元1年至9999年的日历;
2、以标准日历的形式输出,包含月份、星期以及具体某一天对应的年、月、
星期;
3、用数据结构课上所学二叉树及队列顺序存储形式存储;
三、程序设计思路
【一】由于万年历具有以下特点:
1。
平年365天(52周+1天),闰年366天(52周+2天)。
平年2月28天,闰年2月29天。
2。
每400年整一闰,或每4年且不为百年的一闰。
(原因:地球绕太阳一周的时间是365天5小时46秒,为了使一年的天数为整数,将一年的天数定为365天,余下的时间积累起来,四年就是23小时15分4秒,将近一天,把这一天加在某年的二月而成29天,该年称为闰年,其它年称为平年。
但四年加一天又多用了44分56秒,这个数积满400年为三天。
因此400年中只能有97个闰年,所以凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
)
3。
每 4年(3个平年+1个闰年)共208周+5天——注意这个“5天”
每百年共100*(208周+5天)-1天=5217周+5天——注意这个“5天”(整百年暂设为平年)
每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和“1天”(4个整百年只有一个闰年) 即400年一轮回!(原来万年历400年前是一家)
【二】根据万年历以上特点进行编写:
(1)首先对万年历年、月、日进行编写,编写程序先定义每月的天数为28天,如月份为1、3、5、7、8、10、12就定义天数为31天反之如果月份为4、6、9、11就输出天数为30天,由上可见2月份为28天但是如果为闰年就有29天就要定义一个数组存放天数,用while循环控制。
(2)再对其中的星期进行编写:由于公元1月1日设为星期六,故3月1日为星期三,可以用万年3月1日星期算法(特别是那个三)
其公式为:
某年3月1日星期几=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7 某年3月1日星期几=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7
或某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
其中,闰4百年3月1日星期算法(百年%4=0)
其公式为:
某年3月1日星期几=(年+年/4+月星期表+日+2天)%7
例:
1600年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2001年3月1日星期几=(1+1/4+0+1+2)%7=4%7=星期四
2004年3月1日星期几=(4+4/4+0+1+2)%7=8%7=星期一
2008年3月1日星期几=(8+8/4+0+1+2)%7=13%7=星期六
2042年3月1日星期几=(42+42/4+0+1+2)%7=55%7=星期六
其中,平4百年3月1日星期算法(百年%4<>0)
其公式为:
某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
例:1700年3月1日星期几=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:1700年是平年)
1800年3月1日星期几=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:1800年是平年)
1900年3月1日星期几=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:1900年是平年)
1999年3月1日星期几=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一
2100年3月1日星期几=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意:2100年是平年)
2101年3月1日星期几=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二2102年3月1日星期几=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三2103年3月1日星期几=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四
2104年3月1日星期几=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意:2104年是闰年)
9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一
注:按400年一轮回!(400年前是一家)的说法
1600年,2000年是一样的;
1700年,2100年是一样的;
1800年,2200年是一样的;
1900年,2300年是一样的。
其中万年某日星期算法
其公式为:
某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
通同星期偏差表
闰年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天数 31 29 31 30 31 30 31 31 30 31 30 31 星期 3 6 0 3 5 1 3 6 2 4 0 2
平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天数 31 28 31 30 31 30 31 31 30 31 30 31
星期 4 0 0 3 5 1 3 6 2 4 0 2
为对以上的万年历星期的算法是正确的对其进行了以下的计算:
⒈对于二十世纪任意日期可以用公式某日星期几=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7=(19%4*5天+年+年/4+平年月星期表+日+2天)%7=(15天+年+年/4+平年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
1900年元旦 1日=(0/4*5+0%4+1+3)%7=(0+0+4)%7=4
1月表=4(平年)故 4+4=1 即1900年元旦是星期一1949年国庆 1日=(49/4*5+49%4+1+3)%7=(60+1+4)%7=2
10月表=4(平年)故 4+2=6 即1949年国庆是星期六
1999年12月31日 31日=(99/4*5+99%4+31+3)%7=(120+3+34)%7=3
12月表=2(平年)故 2+3=5 即1999年12月31日是星期五
⒉对于二十一世纪新前年虫算法(20%4*5=0)可以用公式:某日星期几=(百年%4*5天+年+年/4+闰年月星期表+日+2天)%7 =(20%4*5天+年+年/4+闰年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
2000年元旦 1日=(0+0/4+1+2)%7=(0+0+1+2)%7=3
1月表=3(闰年)故 3+3->6 即2027年元旦是星期六2018年春节 16日=(18+18/4+16+2)%7=(18+4+16+2)%7=5
2月表=0(平年)故 0+5=5 即2018年春节是星期五
2099年12月31日 31日=(99/4*5+99%4+31+2)%7=(120+3+33)%7=2
12月表=2(平年)故 2+2=4 即2099年12月31日是星期四最后,根据日期是紧挨顺序的,可用顺序存储结构存储,对年、月、星期的算法清晰之后,即可用C语言的形式及C++语言的形式编程。
【三】单元程序设计:
1、闰年函数的定义:
int IsLeapYear( int year )
{
if ((year %4 == 0) && (year % 100 != 0) || (year % 400 == 0) )
return 1;
else
return 0;
2、判断星期的程序设计:
i = Year_days % 7;
printf("Mon Tue Wed Thu Fri Sat Sun\n"); if( i != 0 )
for( temp_i = 0; temp_i < i; temp_i++) printf(" ");
day = 1;
3、用switch语句定义月份:switch( temp )
{
case 1:
printf("January(%d)\n",year);
break;
case 2:
printf("Febrary(%d)\n",year);
break;
case 3:
printf("March(%d)\n",year);
break;
case 4:
printf("April(%d)\n",year);
break;
case 5:
printf("May(%d)\n",year);
break;
case 6:
printf("June(%d)\n",year);
break;
case 7:
printf("July(%d)\n",year);
break;
case 8:
printf("Augest(%d)\n",year);
break;
case 9:
printf("September(%d)\n",year); break;
case 10:
printf("October(%d)\n",year);
break;
case 11:
printf("November(%d)\n",year);
break;
case 12:
printf(" December(%d)\n",year);
break;
4、日期的输出(分闰年及平年,用if语句和while循环实现):if( IsLeapYear(year) && temp == 2)
while( day <= month_day[12] )
{
if( day >1 )
if( Year_days % 7 == 0 )
printf(" \n");
if( day >= 10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
else
while (day <= month_day[temp-1])
{
if( day > 1 )
if( Year_days % 7 == 0 )
printf("\n");
if( day >=10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
printf("\n");
if( getch() == 'q' )
exit(0);
}
getch();
【四】程序框图:
四、程序源代码
#include <stdio.h> //标准输入输出头文件,包含getch()、
scanf()、printf()等语句
#include <iomanip.h> //I/O流控制头文件,含有"%d"(dec 置基数为10)函数
#include<iostream.h> //标准的输入输出流头文件包含scanf()、printf()、cin>> 、cout<<函数
#include<conio.h> //控制台输入输出含有getch()函数
#include<stdlib.h> //包含了的C语言标准库函数如exit()、malloc()、free()
int IsLeapYear(int); //整型闰年的定义
void main() //主程序
{
int i;
int day;
int year;
int temp;
int temp_i;
long int Year_days = 0;
int Year_Start = 1; //万年历的起始时间为公元1年
int Per_Year_Days;
int month_day[]={31,28,31,30,31,30,31,31,30,31,30,31,29}; //定义用于存放每月天数的数组,一三五七八十腊为31天,二月分28天和29天
printf("Please enter the year: ");
scanf("%d",&year); //输入年份,year用引用类型,年数不同时输出随着改变
while(Year_Start < year)
{
if( IsLeapYear( Year_Start ) ) //闰年为366天
Per_Year_Days = 366;
else
Per_Year_Days = 365; //平年为365天
Year_days = Year_days + Per_Year_Days;
Year_Start++;
}
for( temp = 1; temp <=12; temp++ ) //
{
switch( temp ) //计算temp表达式的值
{
case 1:
printf("January(%d)\n",year);//一月
break;
case 2:
printf("February(%d)\n",year);//二月
break;
case 3:
printf("March(%d)\n",year);//三月
break;
case 4:
printf("April(%d)\n",year);//四月
break;
case 5:
printf("May(%d)\n",year);//五月
break;
case 6:
printf("June(%d)\n",year);//六月
break;
case 7:
printf("July(%d)\n",year);//七月
break;
case 8:
printf("August(%d)\n",year);//八月
break;
case 9:
printf("September(%d)\n",year);//九月
break;
case 10:
printf("October(%d)\n",year);//十月
break;
case 11:
printf("November(%d)\n",year);//十一月
break;
case 12:
printf(" December(%d)\n",year);//十二月
break;
}
i = Year_days % 7; //闰年为366天年数除以7的余数
printf("Mon Tue Wed Thu Fri Sat Sun\n");
if( i != 0 )
for( temp_i = 0; temp_i < i; temp_i++)
printf(" ");
day = 1;
if( IsLeapYear(year) && temp == 2) //***此程序的核心,当为闰年时,二月有29天执行while循环,实现星期的换行
while( day <= month_day[12] )
{
if( day >1 )
if( Year_days % 7 == 0 ) //控制每月第一天的位置,满足余数为0
时,另起一行
printf(" \n");
if( day >= 10 )
printf("%3d ",day); //***C语言域宽的设置 %3d表示相邻天数的域宽为3,星期的排列整齐
else
printf("%3d ",day);
Year_days++;
day++;
}
else
while (day <= month_day[temp-1]) //平年的月份
{
if( day > 1 )
if( Year_days % 7 == 0 ) //与闰年时执行条件一样
printf("\n");
if( day >=10 )
printf("%3d ",day);
else
printf("%3d ",day);
Year_days++;
day++;
}
printf("\n");
if( getch() == 'q' )
exit(0); //满足条件时退出
}
getch(); //不满足条件时执行getch()语句
}
int IsLeapYear( int year ) //闰年的定义
{
if ((year %4 == 0) && (year % 100 != 0) ||
(year % 400 == 0) )
return 1;
else
return 0;
}
五、实验结果与分析
【一】实验结果:
(1)2009年1、2、3、4、5、6月:
(2)7、8、9、10、11、12月:
(3)公元100年:公元9999年:
【二】结果分析:
(1)日历的形式为阳历,输出范围为公元1年至公元9999年;
(2)输出结果满足设计要求,可以输出月份,星期,日期且以现在日历的形式输出;
(3)结果能有效区分闰年及平年,每一天的具体天数;
(4)每月前的空格及数字之间的域宽都满足要求:【三】算法效率分析:
(1)时间复杂度:算法中程序的调用都为单层函数调用,没有函数的多层套用,所以时间复杂度为线性阶,即为O(n);
(2)空间复杂度:数据的存取以顺序存储方式存取,没有空间的浪费和压缩存储的现象,所以空间复杂度为O(n)。
六、心得体会:
1. 经过上一个学期对《数据结构》的学习,我们学习了理论知识,了
解了C语言程序设计的思想,这些知识都为我们的下一步学习打下了坚
实的基础。
通过课程设计,一方面是为了检查我们一个学期来我们学习
的成果,另一方面也是为了让我们进一步的掌握和运用它,同时也让我
们认清自己的不足之处和薄弱环节,加以弥补和加强。
通过对万年历的
设计进一步的巩固了用c语言和C++编写程序,并且有利于更好的掌握
程序设计语言!
2. 在万年历的编写过程中也体会到了做事情一顶要细心、认真。
更加
知道了要掌握好基础知识。
还有体会到了成功的感觉!在万年历的设计
过程中更加体会到了团队合作的重要性,在设计的过程中,曾遇到好多
难解的问题,经过与同学的讨论才得以解决,常言道:“一个诸葛亮比
不上三个臭皮匠。
”知道了只有团队合作才会更好的完成设计!也体会
到以后在工作中团队合作的必要性和重要性!
3. 通过本项课程设计也培养了我独立思考、综合运用所学有关相应
知识的能力,掌握工程软件设计的基本方法,强化上机动手编程能力,
闯过理论与实践相结合的难关!
4. 由于程序设计语言是近年在国内外得到迅速推广应用的一种语言。
它功能丰富,表达能力强,使用灵活方便,应用面广,目标程序效率高,
可移植性好,既具有高级语言的优点,又具有低级语言的许多特点。
通
过这次的程序设计更加了解了语言设计的好处和其可用性!
5. 在这次课程设计中也知道了自己的动手能力不强有待进一部的提
高!在设计过程中不能够把书本上的知识与实践相结合,这也就增加了
设计不好该程序的想法!在设计过程中的一次次设计错误增加了我放弃
的想法!不过经过自己的独立思考和同学的帮助终于完成了课程设计!
完成该程序后想起自己以前的每一次对自己失去信心,就觉得并不是在
知识掌握上打败了,而是自己对自己缺乏信心!只要自己对自己不失去
信心相信就可以完成那些以前认为完成不了的事情!也让我懂得了要想
成功首先就必须有很强的自信心!懂得了自己以后要在做任何事情时都
要自信!当自己都不相信自己能够成功时还可能会获得成功吗?
6. 在课程设计的过程中也知道了自己在以前的学习中有很大的不足导
致在设计过程中出现了很多的问题,有些地方看不懂也不知道怎么去设
计,但是在设计过程中也学习了很多,掌握了自己以前没有学好的知识,
虽然一时可以掌握完以前没有学好的知识,不过也给自己敲响了警钟,
在学习中不可以伏于表面,要想学好每一门课程都要踏踏实实,做什么
都不是给别人看的!都是要更好的掌握该门知识,提高自己的自身的修
养,提高自己的能力!为以后的工作打下良好的知识基础和技能基础!
七、老师评语:。