[编程珠玑]-第二章:二分及标识

源于编程珠玑-第二版

问题描述:

A.给定一个最多包含40亿个(2^32)随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(缺少这样一个整数)

1.足够内存情况下:可采用位向量方式,2^32/8 bit =536870912 B 内存空间来表示整数数据,由于位向量表示获得的数据已是有序排列,然后可通过二分查找得到缺少的那位整数。

2.内存有限,可利用外部临时文件空间:从另外的角度利用二分搜索,此时输入文件中的数据是随机排列的,但问题描述中可知2^32个整数是不雷同的,则从32位二进制角度,每一位上的0和1总个数应该是相等的,少的那一部分范围则包含所求的“缺少的一个整数”。

过程:对所有输入的数据进行0/1探测,第一趟先探测第0位(二进制)是0还是1,划分到两个外部临时文件中,一趟结束后选择数量少的那份文件,进行第二趟0/1探测,探测第1位上是0还是1,继续划分到外部临时文件中........

每次减少n/2  n/4 .... 时间正比于n 

内存空间不足则可在一趟中减少输入数据的数量,通过多次输入来完成一趟探测。

例:(作为例子,假设是3位二进制) 通过二分探测,确定缺少的数是101 即=5


另外,对于检查40亿中重复的一个数,也可同理得到(每次选择多的那份文件)

————————————————————

B.将一个n元一维向量向左旋转i个位置(循环左移),当n=8,i=3时,“abcdefhg”-->"defhgabc"

1.内存充足,将前i个元素复制到临时数组,余下的n-i个元素左移i个位置,然后将最初的前i个元素从临时数组中复制到余下的位置。(可能会消耗比较大的内存空间)

2.将此一维向量数组依次左移,直到完成(其中的元素X[i]可能要经过多次换位才能定位到正确的位置,比较消耗时间)

3.“杂技”方案: 移动X[0]到临时变量temp,移动X[i]到X[0], X[2i] 到X[i],X[3i].... 依次直到返回取到X[0]中的元素

,若依次过程无法移动所有的元素,则继续从X[1]开始进行第二次移动 。(i的计算对n取模)

其中总共所需进行的置换趟数 等于 i与n的最大公约数。


public void test2(){
String string="abcdefgh";
char[] x=string.toCharArray();
int rotdist=3;
int m=gcd(rotdist, x.length);
int  j,k;
char temp;
for(int i=0;i<m;i++){
temp=x[i];
j=i;
while(true){
k=(j+rotdist)%x.length;
if(k==i)
break;
x[j]=x[k];
j=k;
}
x[j]=temp;
}
System.out.println(String.valueOf(x));
}

——————————————————————

C.给定英语字典,从中找出变位词集合,如“pots”“stop”“tops”互为变位词。

方案:对字典中的每一次词进行标识,使得相同变位词具有相同的标识,将它们集中进一个集合,即像是划分入同一个散列中。根据单词计算标识,可用字母排序及计数确定,如“mississippi”标识为“i4m1p2s4”。之后将所有标识按升序排列,当需要获得一个单词的变位词集合时,可通过计算该输入单词的标识,再以二分搜索对应的字典标识获得变位词集合。

-----------------问题C主要在于表达“标识+排序+二分搜索”的想法,可应用于较多的情况,如关键字索引情况等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值