[算法]由日期格式函数产生的若干思考 y * 512 + m * 32 + d

[算法]由日期格式函数产生的若干思考 y * 512 + m * 32 + d

完整源码

// Java Code
public class TestDate{
    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);
        int d = Integer.parseInt(args[1]);
        int y = Integer.parseInt(args[2]);
        Date date = new Date(m,d,y);
        System.out.println(date);
    }
}

class Date{
    private final int value;
    public Date(int m,int d,int y){
        value = y*512+m*32+d;
    }
    public int month(){
        return (value/32)%16;
    }
    public int day(){
        return value%32;
    }
    public int year(){
        return value/512;
    }
    public String toString(){
        return month()+"/"+day()+"/"+year();
    }
}

代码说明

 value = y * 512 + m * 32 + d;
 value = y * 2^9 + m * 2^5+ d;

 m = (value / 32) % 16; 
 // 除以32后,剩下 y*2^4 + m(d消掉了,2^4 = 2^9 / 2^5),接着再用16(即2^4)取余,得m

 d = value % 32;   
 // 用32取余自然剩下余数d

 y = value / 512;
 // 用512除法自然得到y

 // 简单猜测计算了一下,输入条件应该限定在:m 取值范围在[0,15] (2^4-1), d 取值范围在[0,31] (2^5-1).

用例测试

测试用例

分别取了边界以及边界+1的几组用例来测m([0,15] )、d([0,31])的取值范围.

InputOutputTest Result
7 11 20157/11/2015
7 11 07/11/0
0 11 20150/11/2015
7 0 20157/0/2015
15 11 201515/11/2015
7 31 20157/31/2015
16 11 20150/11/2015×
7 32 20158/0/2015×

我的思考

  1. 这种把3个输入运用乘法变成1个数字,再运用适当的规则拆回来的思路真是绝顶赞啊! 同时,这种拆的规则也是非常巧妙,我今天算是彻底体会了取余和除法的那种微妙地差别和巧妙地混合使用了,实在开心。

  2. 以前遇见过的类似的运算,就是那种取出每个数位上的数字的题目,比如说 2015 = 2*10^3+0*10^2+1*10^1+5*10^0,需要取出2 0 1 5这几个数字,思路简直异曲同工!上面的代码里会使用512=2^9 32=2^5的确是为了配合日期格式这一目的;因为数值都不大,边界可以快速手工确定,可以的话我挺想看看严谨的数学推导过程。

  3. 对于这样的数字来说,+所起到的或许就是抽象意义上的“连接“的作用而非单纯只有数学意义上的求和吧,或者这么说求和是形式而不是目的;

  4. 写到这里,我终于想到了那个可能的大话题,或许就是所谓的“进制转换”吧,算法真是很有趣呢!

引用参考

图灵程序设计丛书:算法(第4版) 塞奇威克 (Robert Sedgewick) (作者), 韦恩 (Kevin Wayne) (作者),
谢路云 (译者)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值