改变解决问题的思维(1)
2014-09-23 15:38
288 查看
最近在开发彩票应用项目,彩票和其它的应用项目有一点区别就是:彩票计算比重相对大,其它应用逻辑比重相对大。这点微不足道的差别在一个极小的功能点上却能引出代码巨大的差异。
首先介绍本文涉及到的数字彩票的基础概念:单式、复式
一注彩票规定是选择七个号码,只选七个即为单式,选择超过七个号码的组合即为复式。单式就是一注彩票,复式就是多注。
问题一:计算所选号码是单式还是复式,当然还有一种情况就是非法号码,既不是单式也不是复式:
这里以七星彩玩法举例,单式非常简单就不做讨论了。
七星彩就是有7行,每行对于一个list,每个list存储每行选的号码。单式就是每一行都选1个号,复式就是在单式成立的基础上有至少一行选了多于1个号。
我问了3个人,3个人有3种不同计算复式的方法
1:
通过为每一行在变量8bits对应一位,7行对应7位,如果第i行有选号码则第i位置1否则置0,如果任何一行选号码个数大于1个,则8bits最后一位置1。最后如果8位都是1的话就说明每行都有选号,并且有至少一行选号大于1个,确定是复式。
2:
很直观的方法,基本逻辑和上面一样,只是将上面的最后一位作为状态保存下来
3:
遍历出最小值和最大值,最小值大于等于1,最大值大于等于最小值加1即最大值大于最小值
以上3种方法在彩票玩法比较简单的情况下,从简洁性考虑 3 > 2 > 1
问题二:比如有种玩法也有7行,每行分别要选(3,5,2,1,5,6,3)才能成为单式,则复式计算将更复杂。
如果复用上面的3种方法,则会有不同的结果,简洁最低的1方法,反而因为灵活,容易适配新情况,2方法将改动很大,增加很多变量,3方法思路干脆无法解决
如果改变解决问题的思维,使用数学的方法则问题会简单很多
比如对于问题一:
7行的size乘积大于1则为复式
问题二:
数学含义是7行总共选号数量大于每行分别要选的最低数量的总和并且每行所选号数量均大于等于每行分别要选的最低数量。
通过数学的方式可以统一并简洁的解决此类问题,所需代码量小,没有逻辑条件判断,不涉及业务所以产生bug的可能性低
另外除了数学的角度解决问题以外还可以从彩票的体系结构的设计上来解决或变相解决此类问题。
具体方法和内容将在下一篇文章介绍。
首先介绍本文涉及到的数字彩票的基础概念:单式、复式
一注彩票规定是选择七个号码,只选七个即为单式,选择超过七个号码的组合即为复式。单式就是一注彩票,复式就是多注。
问题一:计算所选号码是单式还是复式,当然还有一种情况就是非法号码,既不是单式也不是复式:
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的可能性低
另外除了数学的角度解决问题以外还可以从彩票的体系结构的设计上来解决或变相解决此类问题。
具体方法和内容将在下一篇文章介绍。
相关文章推荐
- 解决了CListCtrl控件当字体改变后,自动调整每行的宽度的问题.
- Mysql master slave因改变hostname导致问题及其解决办法
- 解决javascript动态改变img的src属性图片不显示问题
- ftp文件上传后大小改变问题解决
- 关于KFCEditor控件INPUT等不能拖拽改变大小的问题(已解决)
- 客户端改变状态,服务器服务器端读不到数据的问题,大家有什么好的解决方法.
- PHP中usort在值相同时改变原始位置问题的解决方法
- c# 疑难(一)之打开“OpenFileDialog”文本对话框后默认路径改变问题和解决方法
- 解决javascript动态改变img的src属性图片不显示问题
- netterm访问linux时字体和背景颜色随目录发生改变的问题解决
- ubuntu下chsh命令无法改变默认shell的问题(已解决)
- WPF开发中遇到的问题及解决系列(三):如何改变ListView 中各行的背景色(背景色产生交替效果)
- ThinkPad增值软件Access Connections导致Windows欢迎界面改变问题与解决
- 触发器(当2个表中的相应值改变时同时改变一个表中的一个字段)(同时有处理“无法解决 equal to 操作的排序规则冲突”问题)
- DirectShow改变参考时间解决视频不流畅的问题
- 解决 WinForm 中 TreeView 的 StateImageList 实际显示大小无法改变的问题
- WPF学习心得(1):WPF进行动画后不能改变相对应的属性问题的解决
- ThinkPad增值软件Access Connections导致Windows欢迎界面改变问题与解决
- [网络收集]动态加载CSS,解决母版页无法改变CSS的问题
- 思维的基本过程与解决问题