你是否为每天该上什么课,什么时候上课,什么时候下课而烦恼,不用担心 !!你的救星到了,小爱同学课程表模拟来了!(只是个模拟)
以我的课表为例,主要区别 就在 单双周的不同,比如 单周的时候 周一课表是 大英,高数,和工程制图 周二课表是 计导和C语言,而双周 的时候 周一课表高数和工程制图,周二课表 是 计导
好了,现在发现规律了,只有周一和周二的课表在单双周有区别,周一到周五的课表都完全一样。
现在给出思路:
如果给出一个具体的日期 ,例如11.21号,要知道当天的课表,首先就要知道当天是周几,如果是周一或者周二,那么进一步需要知道11.21号所在的周是单周还是双周,若当天是双周,那么就根据周几以及单双周输出课表,但是如果 当天是周三到周五中的任意一天,那么可以直接输出,因为单双周的周三到周五的课表都是一样的,所以,要解决输出课表的问题,重点就在解决 当天是周几以及当天所处的周数是单周还是双周。
下边是这个问题的思路图:(能力有限,流程图不规范,请谅解,谢谢)
接下来给出这个问题的代码:
#include<stdlib.h>
#include<stdio.h>
/*思路:根据日期 判断周几 -->若为周一或周二 是单周还是双周? 若为其他则直接输出*/
//本程序基于开学第一天9月1日为第一周,单周,且为星期三!!!
int days(int month,int day) // 计算从开学到现在 一共经过多少天 并判断当前周数是单周还是双周
{ int days_on_month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; //分别对应1到12月的天数,a[0]空着
int sum=0;
int i,k;
int S;
for (k = 9; k < month; k++)
sum += days_on_month[k];
S=sum+day;
// int a=S+2;
int a=S+2; //计算一共多少天
int x=a/7; //因为九月一号是周三 所以应该左移两天 +2
if(a%7==0)
{
if(x%2==0)
return 0; //双周 为0
else
return 1; //单周 为1
}
else
{
if((x+1)%2==0)
return 0; //双周 为0
else
return 1; //单周 为1
}
}
void output(int c,int p) //输出课表 将单双周以及周几传进来
{
if(c==6||c==0) //c=0 或 c=6 说明 当天是 周天 或者 周六
printf("呐,果然周末还是喜欢学习呢,最喜欢了!");
else
{ printf("-------------------------------------------------------\n");
printf(" 8:00-9:45 10:15-12:00\t14:30-16:15 \t16:35-18:20\n");
printf("-------------------------------------------------------\n");
if(c==1) //周一
{
if(p==0) //双周
printf("周一 大学英语 高等数学 \t工程制图 \n");
else //单周
printf("周一 高等数学 \t \t工程制图 \n");
}
if(c==2) //周二
{
if(p==1) //单周
printf("周二 计算机科学 \tC语言程序设计\t \n");
else //双周
printf("周二 计算机科学 \t \n");
}
else //周三到周五
{
switch (c)
{
case 3:printf("周三 高等数学 \n");break;
case 4:printf("周四 大学英语 C语言程序设计\t \n");break;
case 5:printf("周五 高等数学 中国近代史 大学体育 \t \n");break;
}
}
}
}
int CaculateWeekDay(int month,int day)//判断当前日期是周几
{
int y, c, m, d, w;
y = 2021 % 100;//年份后两位 如2015 即 15
c = 2021 / 100;//年份前两位 如2015 即 20
m = month; d = day;
w = y + y / 4 + c / 4 - 2 * c + 13 * (m + 1) / 5 + d - 1;//蔡勒公式
while (w < 0)
w += 7;//确保余数为正
w %= 7;
return w; //返回值为 周几
}
int main()
{
int month,day;
printf("请输入需要查询的日期(以点号(.)隔开):");
scanf("%d.%d",&month,&day);
switch(month) //判断日期是否正确
{
case 9:
{
if(day>=31)
{printf("亲,这边建议您重修小学哦,9月只有30天");
return 0;}
else
break;
}
case 10:
{
if(day>=32)
{printf("亲,这边建议您重修小学哦,10月只有31天");
return 0;}
else
break;
}
case 11:
{
if(day>=31)
{printf("亲,这边建议您重修小学哦,11月只有30天");
return 0;}
else
break;
}
case 12:
if(day>=32)
{printf("亲,这边建议您重修小学哦,12月只有31天");
return 0;}
else
break;
}
if((month>=9&&month<=12)&&(day>=1&&day<=31)) //判断非法输入
{
int c=CaculateWeekDay(month,day); //周几
int p=days(month,day);
output(c,p);
}
else
printf("嘛,请输入正确的日期哦!");
}
一共有三个函数,days output CaculateWeekDay.
days 函数的作用是 计算 从开学到查询日期之间共经过了多少天并且判断当前所在的周数是单周还是双周
output 函数的作用是 根据当前日期是周几以及所处周数是否单双周来输出 需要查询日期的课表
CaculateWeekDay. 函数作用是 根据蔡勒公式来计算查询日期是周几
接下来 逐步 理解该代码
从主函数看起,
首先从键盘输入 日期 比如9.6,接下来的一大堆switch 语句是为了 判断输入的日期是否正确,就比如 输入9.31(当然9月是没有31号的,这里只是为了 测试),第一步进入switch语句,case 9 ,判断day是否大于等于31号,32>31,条件成立,输出语句 “亲,这边建议您重修小学哦,9月只有30天”,return 0;程序退出; 如果输入9.30 ,条件不成立,进行break语句,退出当前判断,继续下一个步骤。。。。。。
执行CaculateWeekDay 函数,此函数的功能是 根据输出的日期计算出 该日期是周几,依据就是蔡勒公式,返回值是 0到6的任意一个数,分别代表 周天到周一。
并将这个返回值赋给c
继续下一个函数,days ,此函数 是计算从9月1号到指定日期相差大的天数,例如9.24号和9月1号相差24天,然后根据相差的天数计算出当天日期是单周还是双周,但是这里会有一点点的问题,因为是基于9月1号是周一的情况,但是事实是9月1号是周三,所以应该给计算出的日期加上2,
给个例子吧,例如9月27,距离9月1号27天,按理说是第四周的第六天,但是事实是,9月27号是第五周的第一天,刚好相差2,这里就解释了 为什么要加上2;
好了,这里解释清楚了,继续运行程序,(天数+2)除以7,如果没有余数,就说明当前日期刚好处于某一周的周天,商就是当前日期所处周数,然后判断是否为单双周,相反(这里令商=a,余数=b,)假如有余数,说明当前日期是是第(a+1)周的第b天,这里就解释了为什么程序里有个 (x+1),如果 (x+1)%2=0,那么这周就是双周,相反就是单周,单周返回1,双周返回0;
将这个值赋给p,好了,最后一个函数,将c和p作为参数传给output函数中,这个函数相较于其他的函数比较简单,就是根据参数 c 和 p 判断当前是单周还是双周,以及当前日期是周几来输出课表。
好了,程序到这里就结束了。