VS工具制作控制台日历中算法的启发

   前些天的学习任务是利用VS工具编码实现控制台显示任意年份和月份对应的日历。因为关系到年份和月份,很容易考虑到润年的情况,故功能需求中对于润年的判断及相对应月份天数的判断利用多个for循环和if判断均可轻易实现。但作为该任务最难也是最重要的一点是,当月日历会承接上月的星期而显示一定数量的空白,如图所示:

这个功能的实现,需要找到每个月空白的规律。在没有提示的情况下,萨摩观察了多个月的规律,得到这样的关系:设一只1900年1月1号前为1个空白,则该月末有5*7-1-当月天数即35-1-31=3个空白,则2月初就有7-3=4个空白,以此类推的到一个关系式,设当月出空白书为i,则月末空白数为35-i-当月天数,而第二个月初i下月=7-上月末天数即把i下月=i上月+上月天数-28,且当i=7的时候,实际上没有空白即if(i==7){i=0};综上,可得到判断当月日历前有多少空白的算法编码:

for(int i=1,j=1900,day,month=1;j<=year&&month<=12;j++,month++)
{
if(i==7)
{
i=0;
continue;
}
else if(month==2)
{
if(j%4==0&&j%100!=0||j%400==0)
{
day=29;
}
else
{
day=28;
}
else if(month<=7&&month%2!=0||month>7&&month%2==0)
{
day=31;
}
else
{
day=30;
}
i=i+day-29
}
}

基本思路就是利用之前得到的关系式,通过循环,依次算出从1900年1月1号到输入年份月份后定位的日期退出循环输出i的值。在未学习函数递归之前,可想而知这种通过不对循环的方式进行类推的算法及其冗长和业余,而且代码的正确性尚不能保证。之后,老师给予了算法的新思路,即无论何年,在某月日历前的空白数即为当月1号的星期数(当然如果日历是从周一开始算,即为当月1号星期数-1),这样,只要知道用户输入的年份和月份下,当月1月1号是星期几,就能轻松知道当月日历的空白数,从而将问题转化成寻找星期数。要知道某年某月1月1号的星期,可以在一只1900年1月1号为星期一的条件下,分别计算从1900年到用户输入年份经过了多少天数和用户输入年份当年1月1号到用户输入月份经过了多少天数,求得总天数后,求余7即可知道当月1月1号是星期几。至于对于润平年和大小月的判断,自不在话下。即:

 List<string> day = new List<string>();
                int daysPassedOfYears = 0;
                for (int i = 1900; i < year; i++)
                {
                    if (i % 400 == 0 || i % 4 == 0 && i % 100 != 0)
                    {
                        daysPassedOfYears += 366;
                    }
                    else
                    {
                        daysPassedOfYears += 365;
                    }
                }
                int daysPassedOfMonth = 0;
                for (int i = 1; i < month; i++)
                {
                    if (i == 2)
                    {
                        if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
                        {
                            daysPassedOfMonth += 29;
                        }
                        else
                        {
                            daysPassedOfMonth += 28;
                        }
                    }
                    else if (i < 7 && i % 2 != 0 || i > 7 && i % 2 == 0)
                    {
                        daysPassedOfMonth += 31;
                    }
                    else
                    {
                        daysPassedOfMonth += 30;
                    }
                }
                int daysPassed = daysPassedOfMonth + daysPassedOfYears;
                int dayOfWeek = daysPassed % 7 + 1;
                int blanks = dayOfWeek;
                if (blanks == 7)
                {
                    blanks = 0;
                }
                for (int i = 0; i < blanks; i++)
                {
                    day.Add(" ");
                }
                #endregion
                #region 获取当月所有的天数
                int j;
                if(month==2)
                {
                    if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
                    {
                        j = 29;
                    }
                    else
                    {
                        j = 28;
                    }
                }
                else if (month <= 7 && month % 2 != 0 || month > 7 && month % 2 == 0 && month != 2)
                {
                    j = 31;
                }
                else
                {
                    j = 30;
                }
                for (int i = 1; i <= j; i++)
                {
                    day.Add(i.ToString());
                }

该算法思路清晰明了,方便分析问题。其实,在后续学习了递归之后,对于前一个算法,可以利用递归的方式不断重复使用函数。但尚不清楚在运算速度和占用内存的比较上的优劣。出于在解决该类问题钟不同思路带来的不同算法的思考上,初学者们应当沉下心来,仔细分析问题,尝试思考不同的算法,取其优者。一方面开拓思路,一方面也是一个成熟的程序开发者不得不考虑的问题

原文地址:https://www.cnblogs.com/PoetSAW/p/9195420.html

时间: 2024-11-05 23:31:15

VS工具制作控制台日历中算法的启发的相关文章

巧用开发者工具的控制台来调试页面中的js语句

因为要弄某网页的一个自动登陆工具,所以需要对此网页中的元素利用js进行选取和操作,复杂的js选取如果直接在头脑中想很容易出错,而且一旦出错也不好判断错误原因. 而浏览器带的开发者工具的控制台功能,就给我们提供了一个像在本地开发工具中调试程序一样便捷的功能. 比如要调试博客首页,鼠标右键选择页面中对应的元素,弹出的菜单选择审查元素: 假设我们要选取图中标题的a标签元素,它的id为homepage1_HomePageDays_DaysList_ctl00_DayList_TitleUrl_0,那么我

使用OpenSSL工具制作X.509证书的方法及其注意事项总结

如何使用OpenSSL工具生成根证书与应用证书 本文由CSDN-蚍蜉撼青松 [主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 一.步骤简记 // 生成顶级CA的公钥证书和私钥文件,有效期10年(RSA 1024bits,默认) openssl req -new -x509 -days 3650 -keyout CARoot1024.key -out CARoot1024.crt // 为顶级CA的私钥文件去除保护口令 openssl rsa -in C

ArcMap自定义脚本工具制作

原文 ArcMap自定义脚本工具制作 在制图的前期,一般需要做一些数据的整理,如图层合并.裁剪等工作.虽然在ArcMap中也有提供对应的工具,但使用起来需要点技巧.如批量裁剪,虽然可以实现,但出来的结果会重命名为[图层名]_clip,这样对于配置好整个区域的mxd,需要单独裁剪部分范围数据非常不友好,以为后续工作意味着需要单独给裁剪出来的数据重命名,删除掉后缀_clip才可以统一设置数据源. 解决这个问题其实可以很快速的编写python脚本去实现.但脚本对于一般人来说比较麻烦,每次使用都需要调整

利用 Chrome 开发者工具远程调试 Android 中的原生 WebView

之前写过一篇关于 Android Studio 断点调试技巧 的文章,但都是针对 Native 代码的调试,对于 Hybrid 开发模式下的 WebView 却无从下手.幸运的是,PC 中的 Chrome 浏览器提供的开发者工具能够帮助我们远程调试 Android 中的 WebView 加载的网页. Android 4.4 (KitKat) 开始,使用 Chrome 开发者工具可以帮助我们在原生 Android 应用中远程调试 WebView 网页内容.一起来看看怎么操作吧. 第一步,设置 We

使用MBROSTool 工具制作U盘多启动盘的方法总结

前段时间写了一个自用五合一多启动盘分享--分别用来维护娱乐,wifi密码破解,win&mac登陆密码绕过/清除,反馈的同学还是挺多,觉得大家都有这方面的需求,于是再把自己的使用经验总结一下. 软件的原贴地址:http://bbs.wuyou.net/forum.php?mod=viewthread&tid=330493&extra=page%3D1.希望大家多给M大提供宝贵意见和建议.软件更新了很多版本,不同版本的功能都根据需要进行过增删. 下面就来单独说说使用MBROSTool

使用MBROSTool 工具制作本地硬盘F3救急模式的方法总结

前面写了一篇使用MBROSTool 工具制作本地硬盘多启动盘的方法总结.里面就是可以把一些系统安装到硬盘上面方便使用,比如安装PE到硬盘,不过启动的时候会先进入多UDm菜单,然后选择[启动本地系统]后才会进入本地的系统, 有的人不喜欢这种,或者只希望用PE,那么可以使用F3救急模式,也就是默认就没有变化,开机直接进入本地系统,只有按下F3的时候才进入PE系统,我之前也网上找过很多方法,不过都很麻烦,也很危险,曾经误操作导致分区表错误,丢失掉硬盘上的所有数据,下面就来用MBT实现这个功能. 首先F

安全类工具制作第007篇:行为监控工具的开发

一.前言 现今的杀毒软件都会带有"行为监控"的功能.该功能可以在可疑进程被创建时,或者注册表敏感位置被写入时等情况下,给予用户以提示,让用户来选择是否对相应的可疑操作进行拦截,从而达到主动防御的目的.这样就可以避免传统杀软依靠特征码查杀病毒的滞后性.行为监控工具可以在恶意程序还未正式产生危害时,就将其扼杀. 在制作病毒专杀工具的时候,往往也会使用行为监控工具.比如由微软推出的大名鼎鼎的Process Monitor就是这类工具的典范.通过监控在虚拟机中运行的病毒的种种行为,来采取相应的

C#控制台程序中处理2个关闭事件的代码实例

应用场景 我们开发的控制台应用,在运行阶段很有可能被用户Ctrl+C终止或是被用户直接关闭.如果我们不希望用户通过Ctrl+C终止我们的程序,就需要对Ctrl+C或关闭事件作处理. 处理方法 在.net平台下Console类有个CancelKeyPress事件可以处理Ctrl+C,不过对于直接关闭控制台应用,这种处理就无能为力了. 不过Windows API中有个SetConsoleCtrlHandler函数可以处理这两种关闭事件. C#处理代码如下: 代码如下: static class Pr

原生Js_制作简易日历

javascript制作简易日历,月份信息已经放在一个数组中,在<script>...</script>中编写代码实现其功能 实现步骤 a) 获取需要操作的dom对象 b) 在所有的li上添加鼠标经过的事件 c) 在li的鼠标经过的事件中将所有li的class设置为空,并将当前li的class设置为"active",同时利用innerHTML方法在id为text的div中设置html代码 <!doctype html> <html> &l