一个算法题,聪明人来讨论讨论

志起计算机编程 2014-09-19 02:02:28
加精
四个正数数组(int),每一个数组有100万个数,内存限制1M,如何最优地找出同时在四个数组都出现的整数的个数?
...全文
5198 124 打赏 收藏 转发到动态 举报
写回复
用AI写文章
124 条回复
切换为时间正序
请发表友善的回复…
发表回复
yc1012523 2015-08-18
  • 打赏
  • 举报
回复
引用 49 楼 jwj070524 的回复:
就是根据给定的内存大小分批统计的策略,比如给我的内存只能处理100个数,而且每个数的范围是0~2^32,那么第一轮我只能统计范围从0~99的数,每次统计我肯定要把所有待处理的数都读一遍来确定:0是不是四个数组都出现了?1是不是四个数组都出现了?等等。在第二轮中,我只能统计范围100~199的数:100是不是四个数组都出现了?101是不是四个数组都出现了?.....以此类推。
49楼正解, 典型的时间换空间,可以结贴了!
sichuanwww 2014-09-29
  • 打赏
  • 举报
回复
beyondcj 2014-09-28
  • 打赏
  • 举报
回复
tjwsy 2014-09-28
  • 打赏
  • 举报
回复
int array = int[65535] foreach i in 数组1 { if(array[i]==0){ array[i]++; } } foreach i in 数组2 { if(array[i]==1){ array[i]++; } } foreach i in 数组3 { if(array[i]==2){ array[i]++; } } foreach i in 数组4 { if(array[i]==3){ array[i]++; } } foreach j in array { if(j == 4){ 输出j;//j为存在4个数组中的重复数字 } }
tulip0022 2014-09-28
  • 打赏
  • 举报
回复
哇塞,虽然看不懂,但是感觉好牛逼的样子。 外贸女 VS IT男交友群: 308708519
MMJ288 2014-09-25
  • 打赏
  • 举报
回复
遍历数组就可以
unixplus 2014-09-25
  • 打赏
  • 举报
回复
引用 6 楼 u012999424 的回复:
[quote=引用 3 楼 u013118224 的回复:] 一个int占2个字节,100万占2000000个字节吧
int是四个字节的啊,反正1M是装不下的,就算2000000字节也大于1024平方。[/quote] 这个取决与机器的甚至编译器的
windsunmoon 2014-09-25
  • 打赏
  • 举报
回复
引用 120 楼 jinqian_ki 的回复:
hash一下就可以解决了,1M=1024KB=1024*1024Byte=1024*1024*8 bit 在内存中分配四个个1000000Bit也就是1000000/8/32 size大小的数组,数组中的每一位对应0-10000000的整数,分别遍历每个数组如果出现了某个整数就把内存中对应数组的位置1,重复的只记一次,4个数组都便利完成以后再对内存中的数组进行&操作就可以得出结果了
正解
java圈 2014-09-25
  • 打赏
  • 举报
回复
zise_sss 2014-09-25
  • 打赏
  • 举报
回复
hash一下就可以解决了,1M=1024KB=1024*1024Byte=1024*1024*8 bit 在内存中分配四个个1000000Bit也就是1000000/8/32 size大小的数组,数组中的每一位对应0-10000000的整数,分别遍历每个数组如果出现了某个整数就把内存中对应数组的位置1,重复的只记一次,4个数组都便利完成以后再对内存中的数组进行&操作就可以得出结果了
plfay 2014-09-24
  • 打赏
  • 举报
回复
引用 117 楼 plfay 的回复:
建立一个数组,初始化为-1 a[2^3][2^3][2^3][2^3],每个占16个字节,数组大小2^16(64K),若都是正数,还可以少一半。 之后就简单了,找出相同的数组成员,然后推算出原数就可以了。 赵老师是位好老师
不好意思,这个思维有些问题,若每个字节的前三位相同,后五位分别从1到31都有就全覆盖了, 把&&变成了||
ForestDB 2014-09-23
  • 打赏
  • 举报
回复
不好意思,上述推演有误,不过基本思想是可以用的。 重新推演: 四个正数数组(int),每一个数组有100万个数,内存限制1M,如何最优地找出同时在四个数组都出现的整数的个数? 一共有2 ** 31个正int,如果用一个bit来表示一个int,那么需要2 ** 31 / 8个byte,即256M,4组即1G,如果题目恰好是1G限制的话,那么上述思路可以不加更改,即可以毫无任何压力的算出结果(所以在考虑题目是不是有出错的可能)。 就是1M的限制,那么一些条件就要考虑起来。即2 ** 31 vs 100W大约是2148:1,所以这个分布是相当稀疏的,即有压缩的可能性(编码),那么可以设计一种编码,来充分利用bit状态,继而完成状态的计数(最原始的算法是有空间冗余的,算法简单易实现但空间利用不高)。 又或者可以划分问题,比如先算出两组中都出现的整数的个数,再算另外两组,然后结果再次合并; 再计算两组种都出现的整数的个数的时候,由于1M内存可以表示8388608个整数,可以先将小于8388608的整数中都出现的计数算出来,然后再算大于8388608小于8388608*2的计数;在这个过程中,原始的存100W的数的数组应该也是可以利用起来的。
jackchzj 2014-09-23
  • 打赏
  • 举报
回复
引用 107 楼 jackchzj 的回复:
有错 index{first, end, pos}[n] //n < 1M/3, pos为first在sorted_001中的位置 应该改为 index{first, end, first_pos, end_pos}[n]
错乱了,越改越错,index[n + 1].first_pos == index[n].end_pos + 1;
jackchzj 2014-09-23
  • 打赏
  • 举报
回复
有错 index{first, end, pos}[n] //n < 1M/3, pos为first在sorted_001中的位置 应该改为 index{first, end, first_pos, end_pos}[n]
jackchzj 2014-09-23
  • 打赏
  • 举报
回复
不用每个文件都外排序,一个就可以了 1. 用1M内存外排序第一个文件到sorted_001文件 2. 因为0 <= uint[n] < (2^32 - 1), n == 1000000, 所以 uint[n] 非常离散,为了查找效率,用1M内存为它做个段目录 目录项为结构体数组 index{first, end, pos}[n] //n < 1M/3, pos为first在sorted_001中的位置 因为2^32/1000000=4294,所以 index[n + 1].first - index[n].end >= 4294 3. 结合sorted_001文件及其内存目录求文件1和文件2的交集,这时数据范围应该就大大缩小了,再取剩余两文件求交集即可 无代码,请意会,有错请拍砖。
青蛙工作室 2014-09-23
  • 打赏
  • 举报
回复
这么多数,又限制内存,我只能说呵呵了。
plfay 2014-09-23
  • 打赏
  • 举报
回复
引用 103 楼 plfay 的回复:
排序使用外排序,分成4块,刚好1M,用快速排序排好,然后合并成一个文件 原来的4个文件都如此处理 快速排序在内存中,合并外存 然后读取每个文件的1/4M大小的数据,求相同 若比较完毕,取四段结尾最小的那个,继续读取1/4的数据,求相同 依次到最终结果 这一阶段,在内存中运行。 思路比较简单,可能不是最优。
求相同的阶段应该是两两比较,再比较。
plfay 2014-09-23
  • 打赏
  • 举报
回复
排序使用外排序,分成4块,刚好1M,用快速排序排好,然后合并成一个文件 原来的4个文件都如此处理 快速排序在内存中,合并外存 然后读取每个文件的1/4M大小的数据,求相同 若比较完毕,取四段结尾最小的那个,继续读取1/4的数据,求相同 依次到最终结果 这一阶段,在内存中运行。 思路比较简单,可能不是最优。
plfay 2014-09-23
  • 打赏
  • 举报
回复
建立一个数组,初始化为-1 a[2^3][2^3][2^3][2^3],每个占16个字节,数组大小2^16(64K),若都是正数,还可以少一半。 之后就简单了,找出相同的数组成员,然后推算出原数就可以了。 赵老师是位好老师
sinat_21185607 2014-09-23
  • 打赏
  • 举报
回复
用Bitmap的想法很吸引人哦
加载更多回复(104)

64,670

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧