day035-2019-09-27

使用表驱动编程方式编写打印万年历

表驱动编程设计只是编程的一个技巧,对于复杂的决策,可以将其包装为决策表,然后使用驱动编程的方法解决。这样可以使程序变得清晰简洁,又提高了代码的可修改性。

决策表设计如下:

条件和行动

规则

月份类型

大月

小月

平月(2月)

年份类型

无限制

无限制

平年

闰年

月份天数

31

30

28

29

年份天数

365

366

打印月份天数为31

 

 

 

打印月份天数为30

 

 

 

打印月份天数为29

 

 

 

打印月份天数为28

 

 

 

Java编程实现 

package test;

import java.util.Scanner;

public class Test {

    // 决策表,无限制单元格补上任意符号,保持数组大小为4
    private static String[] monthType = { "big", "small", "flat", "flat" };
    private static String[] yearType = { "any", "any", "flat", "leap" };
    private static int[] monthDay = { 31, 30, 28, 29 };
    private static int[] yearDay = { 365, 365, 365, 366 };

    // 获取相应的月份天数和年份天数,字符串表示,"_"隔开
    // 按照决策,年份的判断依据2月判断,所以下面计算总天数时传2月
    public static String getYearAndMonthDay(int year, int month) {
        for (int i = 0; i < 4; i++) {
            if (monthType[i].equals(judgeMonthType(month))
                    && (yearType[i].equals("any") || yearType[i]
                            .equals(judgeYearType(year)))) {
                return yearDay[i] + "_" + monthDay[i];
            }
        }
        return null;
    }

    public static void printDate(int y, int m) {
        int monthDay = 0;
        int yearDay_sum = 0;
        // 计算从1900年到当前年份的总天数,用于计算星期几
        for (int i = 1900; i < y; i++) {
            //一定要传2月才能得到正确的当年天数
            yearDay_sum += Integer
                    .parseInt(getYearAndMonthDay(i, 2).split("_")[0]);
        }
        for (int i = 1; i < m; i++) {
            yearDay_sum += Integer
                    .parseInt(getYearAndMonthDay(y, i).split("_")[1]);
        }
        yearDay_sum = yearDay_sum + 1;
        monthDay = Integer.parseInt(getYearAndMonthDay(y, m).split("_")[1]);

        System.out.println("日\t一\t二\t三\t四\t五\t六");

        // 除以7便是从那天开始
        int length = yearDay_sum % 7;
        // 之前用空格 打印
        for (int i = 0; i <= length - 1; i++) {
            System.out.print(" \t");
        }
        // 遍历月份 取出多加的monthDay
        for (int i = 1; i <= monthDay; i++) {
            if (yearDay_sum % 7 == 6) {
                System.out.print(i + "\n");
            } else {
                System.out.print(i + "\t");
            }
            // 总天数自增
            yearDay_sum++;
        }
    }
    
    // 判断平年闰年的方法
        public static String judgeYearType(int year) {
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                return "leap";
            }
            return "flat";
        }

        // 判断月份类型
        public static String judgeMonthType(int month) {
            if (month == 4 || month == 6 || month == 9 || month == 11) {
                return "small";
            } else if (month == 2) {
                return "flat";
            }
            return "big";
        }

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年份:");
        // int year = sc.nextInt();
        System.out.println("请输入月份:");
        // int month = sc.nextInt();
        printDate(2017, 10);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值