• 中文
    • English
  • 注册
  • 查看作者
    • 《算法第四版》课后练习题1.2.12答案

      习题1.2.12

      为 SmartDate 添加一个方法dayOfTheWeek(),为日期中每周的日(期)返回 Monday、Tuesday、Wednesday、Thursday、Friday、Saturday、Sunday中的适当值,你可以假定时间是21世纪。

      要点分析

      1.  蔡勒公式

      蔡勒公式(Zeller's congruence),是一种根据日期推算出改天星期几的公式,由德国数学家克里斯提安·蔡勒推算出来。

      公式如下图[1] 

      《算法第四版》课后练习题1.2.12答案

      注意上图中的公式只能计算1582年10月4日之后的日期,但是本题中假设了时间为21世纪,所以不需要考虑这个问题。

      参考答案

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      
      public class Date implements Comparable<Date> {
          private final int month;
          private final int day;
          private final int year;
          public String dayOfTheWeek() {
              String[] week = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
              int y = year;
              int m = month;
              int d = day;
              //如果月份是1月份或者2月份,则看成去一年的13月份和14月份
              if (month == 1 || month == 2) {
                  m += 12;
                  y--;
              }
              int c = y / 100; //获取年份后两位
              y = y % 100;   //获取年份后两位
              int w = (y + (y / 4) + (c / 4) - (2 * c) + ((26 * (m + 1)) / 10) + d - 1) % 7;
              w = (w + 7) % 7;
              return year + "/" + month + "/" + day +": " +  week[w];
          }
      
          public boolean isValidDate(String str) {
              boolean convertSuccess = true;
              SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
              try {
                  format.setLenient(false);
                  format.parse(str);
              } catch (ParseException e) {
                  convertSuccess = false;
              }
              return convertSuccess;
          }
      
           public Date(int month, int day, int year) {
              String str = year + "/" + month + "/" + day;
      
              if (!isValidDate(str)) {
                  throw new IllegalArgumentException(month + "/" + day + "/" + year + "不合法");
              }
              this.month = month;
              this.day = day;
              this.year = year;
      
          }
          public Date(String date) {
              if (!isValidDate(date)) {
                  throw new IllegalArgumentException(date + "不合法");
              }
      //如果final变量选择在构造函数中初始化,那么当类有多个构造函数时,需要在每个构造函数中都对这个final变量进行初始化
              String[] fields = date.split("/"); //正则表达式
              month = Integer.parseInt(fields[0]);
              day = Integer.parseInt(fields[1]);
              year = Integer.parseInt(fields[2]);
      
          }
      
      
      
      /*    public boolean leap_year(int m, int d, int y) {
              if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                  return true;
              }
              return false;
          }*/
      
      
          public int month() {
              return month;
          }
      
          public int day() {
              return day;
          }
      
          public int year() {
              return year;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (!(o instanceof Date)) return false;
              Date date = (Date) o;
              return month == date.month &&
                      day == date.day &&
                      year == date.year;
          }
      
          @Override
          public int hashCode() {
              int hash = 17;
              hash = 31*hash + month;
              hash = 31*hash + day;
              hash = 31*hash + year;
              return hash;
          }
      
          @Override
          public String toString() {
              return month() + "/" + day() + "/" + year();
          }
      
          @Override
          public int compareTo(Date that) {
              if (this.year  < that.year)  return -1;
              if (this.year  > that.year)  return +1;
              if (this.month < that.month) return -1;
              if (this.month > that.month) return +1;
              if (this.day   < that.day)   return -1;
              if (this.day   > that.day)   return +1;
              return 0;
          }
          public static void main(String[] args) {
              System.out.println(new Ex_1_2_12(9, 5, 2018).dayOfTheWeek());
              System.out.println(new Ex_1_2_12(9, 2, 2018).dayOfTheWeek());
              System.out.println(new Ex_1_2_12(2, 29, 2000).dayOfTheWeek());
              System.out.println(new Ex_1_2_12(4, 4, 2006).dayOfTheWeek());
          }
      
      }
      输出:
      2018/9/5: 星期三
      2018/9/2: 星期日
      2000/2/29: 星期二
      2006/4/4: 星期二

      参考资料

      [1] 维基百科:蔡勒公式

    • 0
    • 1
    • 0
    • 2.5k
    • 请登录之后再进行评论

      登录
    • 0
    • 赞助本站

      • 支付宝
      • 微信
      • QQ

      感谢一直支持本站的所有人!

      单栏布局 侧栏位置: