机试算法讲解: 第3题 求两个日期相差的天数

/*
问题:求两个日期相差的天数,连续2天默认为一天。日期形式:YYYYMMDD
输入:
20110412
20110422
输出:
11

思路:方法1:将2个日期都应该化为绝对秒数,然后相减,用绝对秒数之差然后除以24*3600即可

易错点:
time_t mktime(struct tm* tmptr)
double difftime(time_t time1,time_t time2)
char* strncpy(char* strDest,const char* stdSource,size_t count)返回的是strDest
void* memset(void* dest,int i,size_t count)

方法2:
建立一个日期结构体,判断闰年:能被4整除且不能被100整除,或者能被400整除,
建立月份:1,3,5,7,8,10,12有31天
         4,6,9,11有30天
		 2月:闰年29天,平年28天


if( (i/4==0 && i/100!=0) || i/400==0 )

20140122
19891005
8875(正确) 8870错误
年与年相减得diffYear,每一年按照是否是闰年加366或365
小日期的月做减法:依次减去上一个的天数
大日期的月做加法: 依次加上上一个月的天数
小日期的日做减法:依次减去日期
大日期的日做加法:依次加上日期

易错点:
1结构体内不能给数组赋值
2采用加减法计算日期,不需要最终再加上1
3while(scanf("%4d%2d%2d",&y1,&m1,&d1)) 来读取前4位给年,后2位给月

*/


#include <stdio.h>
#include <string.h>
#include <time.h>
#include <memory.h> //memset
#include <stdlib.h> //atoi

//#define leap(y) ((y/4==0 && y/100!=0) || y/400==0),写错了是%而不是/
#define leap(y) ((y%4==0 && y%100!=0) || y%400==0)

typedef struct Date
{
	bool operator < (Date& date)
	{
		if(iYear != date.iYear)
		{
			return iYear < date.iYear;
		}
		else
		{
			if(iMon != date.iMon)
			{
				return iMon < date.iMon;
			}
			else
			{
				return iDay < date.iDay;
			}
		}
	}
	void operator = (Date& date)
	{
		iYear = date.iYear;
		iMon = date.iMon;
		iDay = date.iDay;
	}
	//int iMonArr[2][12] = { {0,31,28,31,,30,31,30,31,31,30,31,30},{0,31,29,31,30,31,30,31,31,30,31,30} };//用两个花括号括起来,结构体内不能赋值
	int iYear;
	int iMon;
	int iDay;
}Date;

void toDate(char* sDate,Date& date)
{
	char sStr[4];
	memset(sStr,0,4);
	strncpy(sStr,sDate,4);
	//Date date;
	date.iYear = atoi(sStr);
	memset(sStr,0,4);
	strncpy(sStr,sDate+4,2);
	date.iMon = atoi(sStr);
	memset(sStr,0,4);
	strncpy(sStr,sDate+6,2);
	date.iDay = atoi(sStr);
	//return date;
}

int Days(Date& date1,Date& date2)
{
	int iMonArr[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31} };
	Date dateMax;
	Date dateMin;
	if(date2 < date1)
	{
		dateMax = date1;
		dateMin = date2;
	}
	else
	{
		dateMax = date2;
		dateMin = date1;
	}
	int iDiffDays = 0,i;
	for( i = dateMin.iYear ; i < dateMax.iYear ; i++ )
	{
		iDiffDays += leap(i) ? 366:365;
	}
	for( i = 1 ; i < dateMax.iMon ; i++)
	{
		//iDiffDays += iMonArr[leap(dateMax.iYear)][i-1];
		iDiffDays += iMonArr[leap(dateMax.iYear)][i];
	}
	//iDiffDays += dateMax.iDay ;
	iDiffDays += dateMax.iDay -1;
	for( i = 1 ; i < dateMin.iMon ; i++)
	{
		//iDiffDays -= iMonArr[leap(dateMax.iYear)][i-1];
		iDiffDays -= iMonArr[leap(dateMax.iYear)][i];//已经没有取当前月的天数了
	}
	//iDiffDays -= dateMin.iDay;
	iDiffDays -= dateMin.iDay -1;
	//return(iDiffDays+1);//这里不需要加1,因为求出来的就是两天之差
	return iDiffDays;
}

//using namespace std;
time_t mk_time(char* sDate)
{
	struct tm tTm;
	char sStr[4];
	//memset(sStr,0,4);
	//memset(tTm,0,sizeof(tm));
	memset(&tTm,0,sizeof(tTm));
	memset(&sStr,0,4);
	tTm.tm_year = atoi(strncpy(sStr,sDate,4)) - 1900;

	memset(&sStr,0,4);
	tTm.tm_mon = atoi(strncpy(sStr,sDate+4,2)) - 1;

	memset(&sStr,0,4);
	tTm.tm_mday = atoi(strncpy(sStr,sDate+6,2)) + 1;//连续2天算两天之差

	return mktime(&tTm);
}

int main(int argc,char* argv[])
{
	//char sDate1[9];
	//char sDate2[9];
	Date date1,date2;
	//int y1,m1,d1,y2,m2,d2;
	//while(EOF!=scanf("%s %s",sDate1,sDate2))
	while(EOF!=scanf("%4d%2d%2d",&date1.iYear,&date1.iMon,&date1.iDay))
	{
		scanf("%4d%2d%2d",&date2.iYear,&date2.iMon,&date2.iDay);
		//time_t tTime1 = mk_time(sDate1);
		//time_t tTime2 = mk_time(sDate2);
		//time_t diffTime = (time_t)difftime(tTime1,tTime2);
		//int iDays = (int)( diffTime > 0 ? diffTime/(3600*24) : (-1)*diffTime/(3600*24) );
		//printf("%d",iDays);
		//Date date1,date2;
		
		//toDate(sDate1,date1);
		//toDate(sDate2,date2);
		int iDays = Days(date1,date2);
		printf("%d",iDays);
	}
	getchar();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问解决能力。此外,在职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值