问题描述
用户可以从每月的 1~最大月份天数(这里统一为 31 天),选出不重复的 7 个数字,进行投注
开奖时会产生7个不同的数字,
根据彩票的数字和开奖彩票的相近程度,划分为1~7等奖,
问题分析
假定玩家在开奖前共计投注 N 张彩票,需要计算出这其中每张彩票的奖项。由于彩票至少为N,所以可以预期算法不会好于O(N),如果在判断一张彩票时,步数过多,那么随着彩票的增多,开奖速度毫无疑问会大幅下降。所以如何判断彩票是中几等奖,直接影响开奖效率。
算法1
以上面的开奖数字1,2,3,4,5,6,7来说,一张彩票的形式是1,2,3,4,5,6,7那么就是1等奖,1等级只有1种可能;而2等奖有(1,2,3,4,5,6,*、*,2,3,4,5,6,7)2种可能;同理3等级有(1,2,3,4,5,*,*、*,2,3,4,5,6,*、*,*,3,4,5,6,7)3种情况,依此类推4等奖有4种可能,5等奖有5种可能,6等奖有6种可能,7等奖有7种可能,共计1+2+3+4+5+6+7=28种情况
1.可以在开奖时,生成1,2,3,4,5,6,7的所有中奖形式,时间花费为O(7)*O(7) = O(49),这项可以忽略
2.尝试对彩票从1等奖到7等奖进行7个奖项的判断;而7个奖项中判断最少次数的1等级只有1种可能,而7等级最多有 7种可能;时间花费为O(7)
3.需要根据开奖等级从开奖数字中取出至多7种可能;时间花费为O(7)
4.另外这里还没有被判断彩票的所有可能,在进行比较之前需要计算出被判定彩票的1~7等奖的所有形式;花费为O(7)*O(7),对每张彩票都要进行这不操作,这部分不能忽略
5.需要根据开奖等级从一张彩票中取出至多7种可能;时间花费为O(7)
这种情况下,1等奖判断需要比较1次……7等奖至多需要7*7,也就是49次,时间复杂度为O(N)*O(7)*O(7)*O(7)*O(7)*O(7) = O(16801N),看起来常数项不小。
实际表现
算法1,实际表现不如人意,处理100000彩票,需要花费12s左右,而且由于总是从1等级判断直到7等奖,它的花费总是 O(N)*O(7)*O(7)*O(7)*O(7)*O(7) = O(16801N);要知道实际情况下,中奖的彩票是极少数的,中大奖的彩票就更加少得可怜,另外一张奖品连7等奖都没有中的话,那是不可能中更高奖项的,因此算法1进行了很多不必要的比较,生成了不必要的中奖可能。
算法2
对算法1不足的地方进行改进
其中,由于中奖的彩票是极少数。现在优先从7等奖开始判断,如果中了7等奖,再去判断是否中了6等奖,一旦不中奖直接丢掉剩下奖项的判断。
另外,被判断的奖票不再每次生成7等奖的所有情况,而是判断每1级别的奖项就生成每1级别的奖项可能。这里时间花费O(49)降低至O(7),总的时间花费降低为 O(2401N)
总的来说,这番改良,可以将预期时间花费为之前的 1/7
实际表现
算法2相比算法1有些许改进,同样处理100000彩票,花费了 1.76s。总的来说,算法1是一个直观的算法,而算法2仅仅是算法1的改良版本。他们的效率我仍然不能接受,所以有了算法3
算法3
想要获得更快的算法,需要对问题进行抽象,同时需要存储更多彩票的信息。
这个问题的关键就是如果快速判断一张彩票的中奖情况,
中奖的判断又可以分为1.是否中奖&