黑马程序员技术交流社区

标题: 今天的一个面试题 [打印本页]

作者: M单色调    时间: 2014-7-18 00:57
标题: 今天的一个面试题
任意输入两个年月份,求出它们之间的天数,不能使用任何Date提供的方法。
作者: ☆枫の云    时间: 2014-7-18 01:05
呃,哪里的面试题啊,黑马的吗?
我想了下,不知道对不对,打个比方:求2014年3月到2012年8月这两个之间的,
可以把天数分为三个部分来求,第一个部分2012年剩下的天数,第二个部分2012年到2014年间整年数的天数,第三个部分2014年过去的天数,然后把三个天数想加就得到总天数了。
大概思路就这样,不知道对不对。
作者: ソi苆僞lè袮    时间: 2014-7-18 01:18
天天酱油~~
作者: idency    时间: 2014-7-18 01:23
我的思路是:
1.将两个时间分别转换成对应的毫秒值;
2.将两个毫秒值相减,获取差;
3.用差值/1000/60/60/24,这样就得出相差的天数.


但是我的date相关的学的不好,代码就不写了
作者: M单色调    时间: 2014-7-18 02:02
☆枫の云 发表于 2014-7-18 01:05
呃,哪里的面试题啊,黑马的吗?
我想了下,不知道对不对,打个比方:求2014年3月到2012年8月这两个之间的 ...

不是黑马的,是我面试西安的一公司的笔试题。面试的时候是手写的我也不知道对不对,你的思路自己可以实现一下,但是首先要判断瑞年,也就是二月份的天数,然后就想到了基础视频中的构表法,把12个月份的天数写到数组中,循环想加。这是只能在一年中的算法,隔年的,判断瑞年或者不是瑞年的,再加356或着355。我的思路是这样的,不过隔年份的不好判断,所以我就只做了一年之中计算天数的!
作者: M单色调    时间: 2014-7-18 02:05
idency 发表于 2014-7-18 01:23
我的思路是:
1.将两个时间分别转换成对应的毫秒值;
2.将两个毫秒值相减,获取差;

嗯,可行!挺好的!不过还得判断瑞年!
作者: hmid    时间: 2014-7-18 02:23
看看这样行不行哦:
public static int getActualDaysOfClass(Calendar from, Calendar to) {
    int count = 0;
    Calendar temp = from;
    //把to这一天也包括
    to.add(Calendar.DAY_OF_MONTH, 1);
    while (temp.before(to)) {
        count++;
        temp.add(Calendar.DAY_OF_MONTH, 1);
    }
    return count;
}
作者: hmid    时间: 2014-7-18 02:28
看看这样行不行:
public static int getIntervalDays(Calendar from, Calendar to) {
    int count = 0;
    Calendar temp = from;
    //把to这一天也包括
    to.add(Calendar.DAY_OF_MONTH, 1);
    while (temp.before(to)) {
        count++;
        temp.add(Calendar.DAY_OF_MONTH, 1);
    }
    return count;
}

作者: hmid    时间: 2014-7-18 02:30
网络问题。多次提交。╮(╯▽╰)╭
作者: 思维    时间: 2014-7-18 12:46
本帖最后由 思维 于 2014-7-18 13:49 编辑

这是我的思路,刚学Java没几天,质量不太好,不过还能计算出来,勉强的看一下吧!:'(
思路: 1.首先判断起始年和终止年每年的天数,包含起始年不包含终止年
         2.判断一年中每个月份的天数
         3.判断输入的日期是否符合要求
         4.计算一年中已经过了的天数
         5.起始年和终止年之间的天数=起始年到终止年整年的天数+终止年已过的天数-起始年已过的天数
  1. class DateDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int y1=1989,m1=7,d1=1;
  6.                 int y2=1990,m2=8,d2=3;
  7.                 int year=0,count=0,result=0;
  8.                 //把整年换算成天
  9.                 for(int i=y1;i<y2;i++)
  10.                 {
  11.                         if(i%4==0&&i%100!=0||i%400==0)
  12.                                 year=366;
  13.                         else
  14.                                 year=365;
  15.                         count+=year;
  16.                 }
  17.                 //终止年已经过的天数加上[起始年,终止年)整年的天数,再减去起始年已经过的天数
  18.                 System.out.println(count+mathDays(y2,m2,d2)-mathDays(d1,m1,d1));
  19.         }
  20.         public static int mathDays(int Y,int M,int D)
  21.         {
  22.                 int days=0,count=0;
  23.                 //判断闰年2月为29天,平年2月为28天,4、6、9、11月为30天,其余月份为31天
  24.                 if(M==2)
  25.                 {
  26.                         if(Y%4==0&&Y%100!=0||Y%400==0)
  27.                                 days=29;
  28.                         else
  29.                                 days=28;
  30.                 }
  31.                 else if(M==4||M==6||M==9||M==11)
  32.                                 days=30;
  33.                 else
  34.                                 days=31;
  35.                 //年份小于0,或月份不在[1,12],或天数不符合前面月份判断条件的,不存在该日期
  36.                 if(Y<0||(M<1||M>12)||(D<1||D>days))
  37.                 {
  38.                         System.out.println("不存在该日期!");
  39.                         return 0;
  40.                 }
  41.                 //计算年份中已经过的天数
  42.                 for(int i=0;i<=M;i++)
  43.                 {
  44.                         if(i==M)
  45.                                 count+=D;
  46.                         else
  47.                                 count+=days;
  48.                 }
  49.                 return count;
  50.         }
  51. }
复制代码





作者: fantacyleo    时间: 2014-7-18 13:02
正确性应该没问题,拿Python内置的功能验算过几个日期。但觉得daysToDate()方法相当ugly,有空再优化。面试手写还不能调试,肯定过不了关的,当练习了。
  1. public class Test {

  2.     public static void main(String[] args) {

  3.         MyDate d1 = new MyDate(1999, 1, 1);
  4.         MyDate d2 = new MyDate(2006, 7, 1);
  5.         System.out.println(d1.daysToDate(d2));
  6.     }


  7. }

  8. class MyDate {
  9.     private static final int[] DAYSINMONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30
  10.         ,31, 30, 31};
  11.     private int year;
  12.     private int month;
  13.     private int day;

  14.     MyDate(int year, int month, int day) {
  15.         this.year = year;
  16.         this.month = month;
  17.         this.day = day;
  18.     }

  19.     public int daysToDate(MyDate aDate) {
  20.         int compareResult = this.compareTo(aDate);
  21.         if (compareResult == 0)
  22.             return 0;
  23.         else if (compareResult > 0)
  24.             return aDate.daysToDate(this);

  25.         int yearDiff = aDate.year - year;
  26.         // same year
  27.         if (yearDiff == 0)
  28.             return daysToDateInSameYear(aDate);

  29.         int totalDaysDiff = (yearDiff - 1) * 365;
  30.         for(int i = year + 1; i < aDate.year; i++)
  31.             if (isLeapYear(i))
  32.                 totalDaysDiff++;

  33.         // days between this and year-end
  34.         totalDaysDiff += daysToDateInSameYear(new MyDate(year, 12, 31));

  35.         // days between Jan 1st and aDate
  36.         totalDaysDiff = totalDaysDiff + 1 +
  37.             new MyDate(aDate.year, 1, 1).daysToDateInSameYear(aDate);

  38.         return totalDaysDiff;
  39.     }

  40.     private boolean isLeapYear(int yr) {
  41.         if (yr % 100 != 0 && yr % 4 == 0 || yr % 400 == 0)
  42.             return true;
  43.         return false;
  44.     }

  45.     private int compareTo(MyDate aDate) {
  46.         if (year == aDate.year) {
  47.             if (month == aDate.month) {
  48.                 if (day == aDate.day)
  49.                     return 0;
  50.                 else
  51.                     return day - aDate.day;
  52.             }
  53.             else
  54.                 return month - aDate.month;
  55.         }
  56.         else
  57.             return year - aDate.year;
  58.     }

  59.     private int daysToDateInSameYear(MyDate aDate) {

  60.         int daysDiff = 0;
  61.         if (month == aDate.month)
  62.             daysDiff = aDate.day - day;
  63.         else {
  64.             for (int i = month; i <= aDate.month; i++) {
  65.                 if (i == month) {
  66.                     daysDiff += DAYSINMONTH[i - 1] - day;
  67.                 }
  68.                 else if (i == aDate.month)
  69.                     daysDiff += aDate.day;
  70.                 else
  71.                     daysDiff += DAYSINMONTH[i - 1];
  72.             }
  73.         }
  74.         if (isLeapYear(year)) {
  75.             if (month * 100 + day <= 228 &&
  76.                     aDate.month * 100 + aDate.day > 228)
  77.                 daysDiff ++;
  78.         }
  79.         return daysDiff;
  80.     }
  81.    
  82. }
复制代码


作者: icris    时间: 2014-7-18 13:08
  1.         public static void compare() {
  2.                 Scanner scanner = new Scanner(System.in);
  3.                 System.out.print("year 1 :\t");
  4.                 int year1 = scanner.nextInt();
  5.                 System.out.print("month 1 :\t");
  6.                 int month1 = scanner.nextInt();
  7.                 System.out.print("date 1 :\t");
  8.                 int date1 = scanner.nextInt();
  9.                 System.out.print("year 2 :\t");
  10.                 int year2 = scanner.nextInt();
  11.                 System.out.print("month 2 :\t");
  12.                 int month2 = scanner.nextInt();
  13.                 System.out.print("date 2 :\t");
  14.                 int date2 = scanner.nextInt();

  15.                 Calendar d1 = Calendar.getInstance();
  16.                 d1.set(year1, month1, date1);
  17.                 Calendar d2 = Calendar.getInstance();
  18.                 d2.set(year2, month2, date2);
  19.                 System.out.println(getDaysBetween(d1, d2));
  20.                
  21.                 scanner.close();
  22.         }

  23.         static int getDaysBetween(Calendar d1, Calendar d2) {
  24.                 if (d1.after(d2)) {
  25.                         Calendar swap = d1;
  26.                         d1 = d2;
  27.                         d2 = swap;
  28.                 }
  29.                 int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
  30.                 int y2 = d2.get(Calendar.YEAR);
  31.                 if (d1.get(Calendar.YEAR) != y2) {
  32.                         d1 = (Calendar) d1.clone();
  33.                         do {
  34.                                 days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
  35.                                 d1.add(Calendar.YEAR, 1);
  36.                         } while (d1.get(Calendar.YEAR) != y2);
  37.                 }
  38.                 return days;
  39.         }
复制代码

能用 Calendar 吧

作者: 思维    时间: 2014-7-18 13:10
fantacyleo 发表于 2014-7-18 13:02
正确性应该没问题,拿Python内置的功能验算过几个日期。但觉得daysToDate()方法相当ugly,有空再优化。面试 ...

高手就是不一样!:funk:
作者: idency    时间: 2014-7-18 15:14
M单色调 发表于 2014-7-18 02:05
嗯,可行!挺好的!不过还得判断瑞年!

要求不是说两个时间之间的天数吗,我觉得不用考虑闰年吧!因为不管是什么年,每一天的时间都是24小时哈!是吧..
作者: Beka    时间: 2014-7-18 15:22
新手路过。
作者: hejinzhong    时间: 2014-7-18 16:02
本帖最后由 hejinzhong 于 2014-7-18 16:16 编辑
  1. #include <stdio.h>
  2. #define leap(y)   (y%4==0 && y%100!=0 || y%400==0)

  3. struct d{int y,m,d;};

  4. long days(struct d d1,struct d d2)
  5. {
  6.         int mon[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} };
  7.         int i;
  8.         long td=0;
  9.         for(i=d1.y;i<d2.y;i++)//
  10.                 td+=leap(i)?366:365;
  11.         
  12.         for(i=1;i<d1.m;i++)
  13.                 td-=mon[leap(d1.y)][i];
  14.         td-=d1.d-1;
  15.         
  16.         for(i=1;i<d2.m;i++)
  17.                 td+=mon[leap(d2.y)][i];
  18.         td+=d2.d-1;
  19.         return td;
  20. }


  21. void main()
  22. {
  23.         struct d d1,d2;
  24.         long td;
  25.         printf("first date:");
  26.         scanf("%d-%d-%d",&d1.y,&d1.m,&d1.d);
  27.         printf("second date:");
  28.         scanf("%d-%d-%d",&d2.y,&d2.m,&d2.d);
  29.         td=days(d1,d2);
  30.         printf("%ld",td);
  31. }
复制代码
先说下思路<假设输入的日期都是合法的>
思路:分为年月日三部分差的和作为最后的结果
(1)判断起始日期和结束日期之间相差的年。将这些年累加(每年判断是否是闰年,通过一个全局变量
(2)减去起始日期的已过月份所占的天数,加上结束日期已过月份的天数(通过查表法累加或减)
(3)减去起始日期的所在的天数,加上结束日期所在天数(通过查表法累加或减)上面是C实现的,java还没写,意思都一样


作者: 思维    时间: 2014-7-18 20:41
idency 发表于 2014-7-18 15:14
要求不是说两个时间之间的天数吗,我觉得不用考虑闰年吧!因为不管是什么年,每一天的时间都是24小时哈!是吧 ...

闰年多一天!就多24个小时呢?
作者: zhaoalei    时间: 2014-7-18 21:24
应该用毫秒算》》。。
作者: 杨冬冬    时间: 2014-7-18 23:00
理了半天,没有思路过来看看




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2