改变解决问题的思维(1)

最近在开发彩票应用项目,彩票和其它的应用项目有一点区别就是:彩票计算比重相对大,其它应用逻辑比重相对大。这点微不足道的差别在一个极小的功能点上却能引出代码巨大的差异。


首先介绍本文涉及到的数字彩票的基础概念:单式、复式
一注彩票规定是选择七个号码,只选七个即为单式,选择超过七个号码的组合即为复式。单式就是一注彩票,复式就是多注。


问题一:计算所选号码是单式还是复式,当然还有一种情况就是非法号码,既不是单式也不是复式:
bool isSingle(list1...7)
bool isMultiple(list1...7)


这里以七星彩玩法举例,单式非常简单就不做讨论了。
七星彩就是有7行,每行对于一个list,每个list存储每行选的号码。单式就是每一行都选1个号,复式就是在单式成立的基础上有至少一行选了多于1个号。


我问了3个人,3个人有3种不同计算复式的方法
1:
byte 8bits = 0x00000000;
i from 1 to 7:
    if list(i).size>0 then (8bits set i-bit to 1)
    if list(i).size>1 then (8bits set last-bit to 1)
if(8bits == 0x11111111) true;
else false;




通过为每一行在变量8bits对应一位,7行对应7位,如果第i行有选号码则第i位置1否则置0,如果任何一行选号码个数大于1个,则8bits最后一位置1。最后如果8位都是1的话就说明每行都有选号,并且有至少一行选号大于1个,确定是复式。


2:
bool bigger_than_one = false;
i from 1 to 7:
    if(list(i).size==0) then false;
    if(list(i).size>1) then bigger_than_one = true;
if(bigger_than_one) then true;
else then false;




很直观的方法,基本逻辑和上面一样,只是将上面的最后一位作为状态保存下来


3:


int min, max;
i from 1 to 7:
    if(list(i).size<min) then min=list(i).size;
    if(list(i).size>max) then max=list(i).size;
if(min>=1&&max>min) then true;
else then false;




遍历出最小值和最大值,最小值大于等于1,最大值大于等于最小值加1即最大值大于最小值


以上3种方法在彩票玩法比较简单的情况下,从简洁性考虑 3 > 2 > 1


问题二:比如有种玩法也有7行,每行分别要选(3,5,2,1,5,6,3)才能成为单式,则复式计算将更复杂。
如果复用上面的3种方法,则会有不同的结果,简洁最低的1方法,反而因为灵活,容易适配新情况,2方法将改动很大,增加很多变量,3方法思路干脆无法解决


如果改变解决问题的思维,使用数学的方法则问题会简单很多


比如对于问题一:
list1.size * list2.size * list3...7.size > 1 


7行的size乘积大于1则为复式


问题二:
list1.size + list2.size + list3...7.size > (3 + 5 + 2 + 1 + 5 + 6 + 3) &&
(list1.size/3) * (list2.size/5) * (list3.size/2)... >= 1


数学含义是7行总共选号数量大于每行分别要选的最低数量的总和并且每行所选号数量均大于等于每行分别要选的最低数量。


通过数学的方式可以统一并简洁的解决此类问题,所需代码量小,没有逻辑条件判断,不涉及业务所以产生bug的可能性低


另外除了数学的角度解决问题以外还可以从彩票的体系结构的设计上来解决或变相解决此类问题。
具体方法和内容将在下一篇文章介绍。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值