题目:
有 34 个学生,每个学生从 0-33 个数字中选择了 5 个数字,作为输入;
如下图:
`
06,10,14,16,26 14,20,21,22,26 01,10,11,12,13 11,01,12,02,17 10,11,12,17,19 09,17,13,15,32 12,19,20,21,22 06,13,29,30,17 20,30,33,06,08 04,08,14,20,30 12,15,17,20,29 04,11,15,21,26 01,06,12,20,29 01,02,06,11,23 02,27,20,12,10 02,10,17,25,26 08,18,19,20,28 10,21,25,28,29 02,08,18,27,32 05,20,21,27,33 07,12,18,27,32 13,15,18,20,22 01,03,04,07,09 05,06,12,21,30 07,12,18,27,32 02,03,06,08,15 02,03,06,10,16 14,15,19,25,06 25,26,27,28,29 04,01,14,25,30 01,02,30,31,32 04,05,14,15,29 03,15,23,32,33 01,05,26,12,33
`
现在随机从 34 个学生中挑选 5 名学生,合并他们选择的所有数字组合;将这些数字组合全部写入文件,要求要去重重复的组合。
情形一: 如果不去重,那么组合数就有:$C^{5}_{34}$组合数,总共为 278256, 写入文件中数据量不大;
但是目前遇到的问题:
如果学生数为 50 个,求 20 个学生选择的所有组合,那么所有的组合$C^{20}_{50}$组合数为:47129212243960,那么这个数据量非常巨大,采用什么的方案写入文件并去重比较好呢?
1 arrow8899 2019-09-10 17:16:20 +08:00 ![]() 跟学生总数没关系吧,每个学生的选择都是独立互不影响的,50 个学生也就 A(50, 5) * 20 = 5085024000,去重可以用布隆过滤器。 |
![]() | 2 wanganjun 2019-09-10 18:26:05 +08:00 用 byte 代替字符串:0-33 用一个 byte 表示足够了,一个数字组合占用空间 5 个 byte。 这样一个数字组合就可以用一个 int64 来表示,去重功能就可以直接用比较 int64 是否相同就可以了 |
![]() | 3 wanganjun 2019-09-10 18:28:55 +08:00 还可以再极端一点,0-33 用 4 个 bit 就可以表示,这样一个数字组合占用空间 2.5 个 byte,可以直接用 int32 表示 |
![]() | 4 wanganjun 2019-09-10 18:30:41 +08:00 上一个回答好像不对。。。 |
5 layorlayor 2019-09-10 19:23:02 +08:00 1. 把 50 个人分成两堆,一边 25 人, 两边分别求出每个人数组合的状态,一共 2^25 种组合 2. 从一边选 k 个人,0<=k<=20,那另一边选 20-k 个人,组合一下,复杂度 20 * (2^20) 3. 以上口胡。 |
6 layorlayor 2019-09-10 19:32:38 +08:00 @layorlayor 好像说错了 忽略我吧 |
7 smdbh 2019-09-10 20:19:45 +08:00 via iPhone 如果大家选择一致就是 c33-5,有一个变化就是 c33-6,学生够多,就是 c33-33,然后全部加起来? |
![]() | 8 mathzhaoliang 2019-09-10 20:31:28 +08:00 ![]() 你需要一个不重复不遗漏生成所有组合数的算法,而不是全部生成然后去重。 可以参考 knuth 计算机程序设计艺术第四卷组合算法。 |
![]() | 9 longzhixin OP @arrow8899 迟来的感谢,非常感谢 |
![]() | 10 longzhixin OP @wanganjun 非常感谢 |
![]() | 11 longzhixin OP @layorlayor 感谢 |
![]() | 12 longzhixin OP @mathzhaoliang 专门买了本,看了组合算法 |
![]() | 13 longzhixin OP @smdbh 感谢 |