《编程珠玑》之一维向量旋转

chapter 2 ,书中的观点:

@1,问题定义(确定用户的真实需求)是程序设计的根本。

@2,优秀的程序员都有点懒,他们坐下来努力思考最佳解决问题的方法,而并不急于使用最开始的想法编程。

 

第二章作者直接给出三个问题,找出一个40亿个乱序的32位整数,的缺失的整数;将一个n元一维向量左旋i个位置;给定一个英文字典,找出其所有变位词的集合。

 

第一个问题:最开始的想法,是sort后,在 i++ 遍历一个个对比元素,时间复杂度是sort的nlog(n)。  优化的方法,是运用二分法,对于40亿个元素,将其二进制表示的最高位是1的元素,分为一类;是0的元素,分为另一类。那么必定有一类的元素总和,小于 2^32/2,选取该类,对该类的元素的第二个高位是1的元素,分为一类;是0的元素,分为另一类。那么必定有一类的元素总和,小于 2^32/4,选取该类,进行类似的迭代。很明显,该方法循环不超过32次,而每次的分类时间复杂度为n,因此总的时间也是n,比第一种方法快log(n)倍!

 

第二个问题:最容易想到的,是将向量的左边i个元素,拷贝到临时空间,然后将右边的n-i个元素移动到最左边,接着把临时空间的i个数据,拷贝到最右边;缺点(耗空间)。如果写个函数,函数的功能是对向量左移一位,那么需要调用该函数i次;缺点(耗时)。如何做到不耗空间,由不耗时间呢? 除了作者称为"杂技"的程序,本人并没去看。书中给出了“能满足时间空间要求,代码非常简短,很难出错”的实现方法:AB -> BA ,A求逆Ar,B求逆Br,(ArBr)r 的到 BA.  不得不佩服,用这个方法实现起来的代码,想出错都难!

示例: str=abcdefg,i=2, reverse(0,i-1), reverse(i,n-1), reverse(0,n-1)

                                               ba cdefg             ba gfedc             cdefgab                 (如意会不清,可想象下书中的翻手示意图)

 

第三个问题:肯定不能强行遍历一个单词的所有可能组合,然后对每个组合在字典中查找验证。作者有意展示了下“估算”的技巧,通过(π秒就是一个纳世纪,也就是1年≈3.14*10^7秒)估算一个含有22个字母的单词,排列需要数十年的运算时间! 然后给出了基于“键值”的方法,字典中的一个单词的所有变位词,都可以用唯一的一个键值表示。键值的选取,就是该单词的字母按字段顺序的排列。这个用c++的map数据结构,很容易实现。

 

期待中秋节的到来,因为又可以放假了,现在洗澡睡觉吧!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值