• 中文
    • 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.9k
  • 请登录之后再进行评论

    登录
  • 0
  • 单栏布局 侧栏位置: