第一章 开篇
友好的对话
在别人不会问问题时,引导他去问问题也是一个很大的学问。
Jon与一个程序员问的问题而展开。
问题
如何将1千万条记录排序?(都是七位的电话号码)最好是将时间控制在十秒钟左右,如果不行,几分钟也可以,但是不能超过十分钟,同时不可超过一兆的内存。
Jon先生要求我思考一分钟,并给他一个答案。
我的答案:
一是使用链表的方式,运用插入排序的方法。
二是使用归并排序算法(尽管直至此时,我仍没有成功的完成归并排序,但我推荐他这么做的原因是其时间复杂度最低,nlogn)下面向您简述我了解到的归并排序算法的原理:
归并排序算法:
首先将数组分为两部分,然后将ab两部分分别排序,最后将ab两部分合并为一个数组。将ab中待插入的元素作比较,将较小的插入L,然后将插入的数组定位器后移,继续比较两个数组的待插入元素,嗯,直到a与b中所有元素全部插入到L中,嗯,此时结束。
当然以上并没有说明如何将ab数组排序,这里其实有一个很好的办法,就是将其分割若干次,直至每个数组都是单一元素数组,那么数组遍都是排序排好序的数组。
Python的实现:
def marge(A, B):
my_list = []
for a in A b in B i in range(len(A) + len(B)):
if a > b:
my_list[i] = a
else:
my_list[i] = b
return my_list
def marge_sort(L):
A = L[:len(L)/2]
B = L[len(L)/2:]
marge_sort(A)
marge_sort(B)
L = marge(A, B)
''' 只是把代码写出来,还没有调试检验 '''
以上便是我的解答,非常奈斯!
Jon的答案
Jon思考后的解决办法是使用位图,我觉得原因有以下几点:
-
1千万条记录又是用一兆的内存直接运行的,怕是不行。
复习一下组成原理的知识。
1 Byte = 8 bit
1 KB = 1024 Byte = 8 * 1024 bit
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
二进制数程序中,每个零或一就是一位。位就是bit。
假使这里运用八位二进制表示一个数字,且每个电话号码都为7位,则有
(1024×1024×8) / (8 * 7) = 143000(Jon老师可能将1000视为1024)。
Jon的另一种方法似乎可以存放更多的数,即每个号码用32位二进制表示,则有
(1000×1000*8) / 32 = 250000,即1M可以存放250000个号码,因为最大的7位数为9999999,便有
9999999 / 250000 = 40
嗯,40次才能装得下1000万个电话号码。
以上次多趟排序的空间大小分析。
多趟排序的原理是第一趟排序中将0-250000之间的任何整数读入内存,并对着25万个整数排序,然后写到输出文件中,重复40次则排序完成。 -
Jon说此问题若是采用归来排序可能需要几天的时间(包括写程序,调试,运行。我觉得晚上回去可以试一下)。
-
位图的方式更加简明记,即将大小为n的数用1占位表示第n个数是存在的,即array[1048256] = 1,即表示电话号码1048256存在。好了,下面来简述一下Jon的方法——位图的方法:
第一步就是初始化一个大小为一千万的shuzu。
第二部遍历输入文件。如果某个数存在则设其位置为1。
第三步,输出答案。
比较我与Jon的答案:
哇哇。Jon的解法真的简单明了,可惜可惜!为什么我们早点想到这个方法,脑中是有闪过这个想法的。但是觉得不成熟也没有在思考,而是转念去想归并排序这个方法了,是什么原因?我觉得是思维不愿意去思考的原因,前几天还看了关于开发思维的书籍,里面讲的:同时从好几个方面来思考方法。不要只从一面来思考。先不着急着否定了某个想法。先记下来。可惜可惜!
但是这个方法好像有问题。不是这个解法有问题,自己该用什么数据结构的存储,Jon首先说用字符串的方式。然后我说用数组的方式,我觉得都可以。好的牛皮!
习题1.6
2.如何使用位逻辑运算符(如与,或,移位)来实现位向量?
首先我因为不明白为向量是什么而搜索以下这个问题:
“什么是位向量?”
我看了一下百度百科,CSDN的zeb_perfect先生以及远航先生的博客,我决定自己先来解决问题(笑)。
因为百度的解释太深奥,不是看的很懂,zeb_perfect先生解读的可能有些偏差(无意冒犯),远航先生的解读过于深入,暂时不想看。但是我将二位的博客都添加到我的收藏夹下,待我先思考一番之后,且是全面的思考,定是全面的思考,再来拜读二位的博客。
好了,废话不多说,先来探究问题,如果Jon先生在我面前,倘若有幸见到先生,那我一定会说:您这是问的什么jb问题?可不可以不要那么抽象呢?而且也不明确。
再读一遍问题:“如何使用位逻辑运算符(如与,或,移位)来实现位向量?”我还是不明白要问的是什么?原因以下1.可能是不明白什么是位向量?我的理解:
位向量就是位图的延伸,使用多个位来表示一个单位,我们且将其称之为位向量。
哇哇哇~,如此简洁明了,怕是只有我能做出这一定义了,好了,不再废话,我的脑海中给出的答案现在有两个:
第一个是假设用四个位为一个单位,那么第一个与第二位的与可以表示一个单位的性质或者属性,那么这个这个位向量可以表示4+n个属性。
第二个通过使用位置位逻辑运算来生成其他几个位(这个也还是可以)。
好了,先到这里吃饭。
网友评论