编程珠玑第二章总结:
来源:互联网 发布:淘宝的网商银行贷款吗 编辑:程序博客网 时间:2024/05/18 17:44
[0]:问题A:给出一个顺序文件,它最多包含40亿个随机排列的32位整数。找出一个不在文件中的32位整数。
分析:如果内存足够的话,可以采取第一章的位图排序法,以O(n)的效率就可以解决。
如果内存不足的话,但是有几个外部文件可以存储数据,那么就可以采用二分查找的思想来解决问题!!!这里的思路比较巧妙,它不是通常意义上的二分查找,但是思维模式很相似.我们可以通过扫描输入文件,将第一位是0的写入一个文件,将第一位是1的写入第二个文件,然后对比这两个文件的数据个数,可以肯定的是:[较少的一个文件必然含有缺少的整数],然后可以递归的处理问题,将这个文件看作是新的输入文件,并且记录丢失的整数相应的位数.用python描述的代码如下:
def find_lost(myarray): array = myarray lost = 0 for bit in range(31,-1,-1): zero_array = [] one_array = [] checknum = 1<<bit for num in array: if(num&checknum == 0): zero_array.append(num) else: one_array.append(num) if(len(zero_array)<len(one_array)): array = zero_array else: array = one_array lost += checknum return lost
当然这个代码还可以进行优化,但是基本结构就是这样了.
问题B:二、类似字符串循环移位举例:比如abcdef 左移三位,则变成defabc条件限制:空间限制:可用内存为几十字节 时间限制:花费时间与n成比例
对于这个问题首先给出最简单的解法:逆转法,这个思路相当的巧妙:要处理的字符串时ab(a是需要移动的字符串),aR代表对a进行反转,那么可以这样处理,(aRbR)R就得到了所需要的结果
def myreverse(left,right,L): beg,end = left,right-1 while(beg<end): L[beg],L[end] = L[end],L[beg] beg += 1 end -= 1def Reverse(i,s): myreverse(0,i,s) myreverse(i,len(s),s) myreverse(0,len(s),s)
然后还有稍微复杂一点的办法,但是效率稍高:
对数组中的元素进行步长为step的移位,比如a[0]<-a[step]<-a[2*step]…<-a[k*step](k*step<=n<(k+1)*step)<-a[0],这样就进行了一次循环移位,然后对a[1],a[2]…a[i-1]进行相同的操作,最后就得到了将前i个字符进行循环移位的结果.而且对比取逆法,只需要对元素操作一遍(交换的时候是操作2遍)
def myswap(i,L): def move(beg,step,L): i = beg+step t = L[beg] while(i<len(L)): L[i-step] = L[i] i += step L[i-step] = t for i in range(i): move(i,3,L) return L
问题C:、给出一个英语字典,找出所有变位词集。 比如age的变位词是age,aeg,eag,ega,gae,gea。
思路比较简单,可以对每一个单词进行一种标志,将所有变位词都转换到一个标准的标志比如bac,cab,acb->abc,然后通过对比标志来判断,假如只给了字典且不让预处理,那么就只能一个个的进行比较了.
def Get_Count(word): count = [0]*26 for w in word: count[ord(w)-97] += 1 ans = '' for key,item in enumerate(count): while(item!=0): ans += chr(key) item -= 1; return ansdef myquery(obj_word,word_dict): count = Get_Count(obj_word) for words in word_dict: if(count == Get_Count(words)): print(words)
假如可以进行预处理,那么就将字典处理成一个开放散列结构,将相同的标志收集到一块来:
def preprocess(word_dict): New_dict = {} for words in word_dict: count = Get_Count(words) if(New_dict.get(count)==None): New_dict[count] = [words] else: New_dict[count].append(words) return New_dictdef new_query(obj_word,new_dict): return new_dict[Get_Count(obj_word)]
问题2,如何在4300 000 000个32位整数里面找出一个至少出现2次的整数,这个和问题A的思路基本相似,只需要将二分的策略改为含有数据较多的那一个区间,下面简单证明一下:
首先知道当前输入里面一定有重复的数字,不妨假设两个文件A,B分别包含了x,y个数据,x+y=N,x>y .因为N>2k=>x>N2(k代表当前还没有处理的位数) ,A没有重复数据的情况下最多应该包含了所有2k−1<N2 种数字,那么x>N2 是不合理的。因此A一定含有重复数据。
问题8:给定一个n元实数集合,一个实数t和一个整数k,如何快速确定是否存在一个k元子集,其元素之和不超过t.
[1]:直接排序,然后找到最小的k元集合。
def fast_find_k(array,k,t): array.sort() sum_min_set = 0 for item in array[0:k]: sum_min_set += item return sum_min_set <= tprint(fast_find_k([9,8,7,6,5,4,3,2,1],3,5))
[2]:采用快速选择算法,找到一个第i小的元素需要花费的时间为O(n) ,所以选择k元最小集合只需要O(kn)
[3]:堆排序算法:O(n)+kO(logn),分别是构建一个堆的时间和取 k个小元素 .更快速的思路是应该用Topk最小堆的算法构造。
问题9:这就是一个简单的数学题,不妨假设两种方式的时间消耗为kO(n),O(nlogn)+kO(logn) ,分离变量计算得k>=nlognn−logn
问题10,用水去算体积。。。。
0 0
- 编程珠玑第二章总结:
- 《编程珠玑 》第二章 问题A 总结
- 编程珠玑第二章
- 编程珠玑第二章
- 编程珠玑第二章
- 编程珠玑第二章
- 编程珠玑 第二章
- 编程珠玑 第二章 算法
- 编程珠玑第二章习题
- 编程珠玑之第二章
- 编程珠玑第三章总结
- 编程珠玑第四章总结
- 《编程珠玑》 第二章 算法 习题
- 《编程珠玑》第二章-循环移位
- 编程珠玑第二章变位词1
- 编程珠玑第二章习题2
- 编程珠玑-第二章旋转算法篇
- 编程珠玑第二章旋转算法
- spring4整合Hibernate4过程中遇到的事物管理问题
- 物联网开源硬件
- 二次元世界
- jQuery动画效果
- 人生如梦
- 编程珠玑第二章总结:
- Android开发学习之路--React-Native之初体验
- LDA2vec: LDA + word2vec
- hadoop2.x常用端口、定义方法及默认端口、hadoop1.X端口对比
- Android多渠道打包
- ACM-2011 多项式求和
- TortoiseGit 使用教程
- VS设置使用UNICODE
- MyBatis级联探讨第三篇——一对一和一对多