【读书笔记】《编程珠玑》第一章之位向量&位图
此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略。共分三篇,基础,性能,应用。每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣。
自个呢也是头一次接触编程技巧类的书籍,而且算法数据结构方面的知识储备实在是薄弱,这么看来,纯粹找虐啊orz。今此行为,歇业养伤,实属无聊。也可说是自打毕业后,看书如打仗,自视身处“安安稳稳的和平年代”,闲来了也就闲着,忧患意识甚少,有也退退缩缩。话说回来,这本书不像CLRS那种难打的硬仗(现在想想都脑仁疼啊),《Programming Pearls》这么个好对手,排烦解闷也正好练练身手!
废话了一大堆,嘿嘿,看官轻拍。那下面就来看看第一章讲了些啥~
问题
怎样给一个最多包含1千万条记录且每条记录都是7位的整数的磁盘文件排序?
准确描述
这里书本对问题抽象出了精确的描述:
输入:一个最多包涵n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数相关联。
输出:按升序排列的输入整数的列表。
约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。
解决方案
归并排序。联想下归并排序的缺点:需要O(n)的辅助空间,可知他必将多次的多写一块额外的工作文件or内存。优势:只需读取一次。劣势:需要数次操作额外文件。
分批读入数据,然后使用快速排序。每个整数用32位即4字节表示最多可表示带符号的2^31-1>9 999 999,计算10^7/(10^6/4)可得,40次读取排序可以达到目标。优势:快。劣势:多次读取数据,多趟算法。
使用位图数据结构。这个一个(10^7/32 + 1) 行 (32) 列的大表:
31 30 ... 1 0 31 30 ... 1 0 ...... 31 30 ... 1 0 31 30 ... 1 0
如果数据是{2,3,5},那么第一行上就会是:0000 0000 0000 0000 0000 0000 0010 1100。很明显的,文件里所有的整数都可以在这张表里找到对应的位置,聪明如你,这就是一个大小为10^7/32 + 1的int[],具体的算法是这样的:
package chpt1; import java.util.List; /**
* Created by wqi on 2016/10/22.
*/
public class BitSort {
// 位向量,也可称作位图,这里为了形象化,取作bitMap.
private int[] bitMap; // i >> 5即每32个数为一组,也就是数组重的一个int元素。 i & 0x1f 相当于取该数对32取模,就找到了该数对应的位,|= 即为置1。
private void set(int i) {
this.bitMap[i >> 5] |= (1 << (i & 0x1f));
} // 和set()本质上的区别就是 &= 将该数对应的位置0
private void clr(int i) {
this.bitMap[i >> 5] &= ~(1 << (i & 0x1f));
} // 返回该数对应的位为1或为0
private int test(int i) {
return (this.bitMap[i >> 5] & (1 << (i & 0x1f)));
} public void sort(List<Integer> list) {
this.bitMap = new int[list.size() / 32 + 1]; for (int i = 0; i < this.bitMap.length; i++) {
clr(i);// 第一阶段将所有的位都置为0。
}
for (int i = 0; i < list.size(); i++) {
set(list.get(i));// 第二阶段读入文件中的每个整数来建立集合,将每个对应的位都置为1。
}
for (int i = 0; i < list.size(); i++) {
if (test(i) == 1){
// 第三阶段检验每一位,如果该位为1,则输出这个数。
}
}
}
}
优势:只需要读取一次文件数据,且不需要额外文件。而且使用的是基本的位操作,速度会更快。劣势:没有,这算法相当友好。
总结
这一章在英文原版中名为 Cracking the Oyster ,直译为「美妙的(也可作开裂的)牡蛎」。和开篇概览中提到的『对实例研究的深入思考不仅很有趣,而且可以获得实际的益处』很贴切,牡蛎多鲜啊,pearls 的美也很直观的看到。再扯句题外话,貌似在西方国家 Oyster 这个词的意味是很好的,沙翁的台词中有 the world is my oyster 意译可表示成——我可以为所欲为啦。
位图这种数据抽象确实很有趣!巧妙的解决了这种看上去很乍乎的大数据问题。在网上也了解到,很多时候在处理大批量数据时,都可以考虑使用该数据结构,这点往后有待补充,希望在这再写几篇做到『举一隅,不以三隅反』。另外,针对位图这一数据概念,Java已经有操作起来非常简单的实现了,就是BitSet(),该集合类初始范围在0~63(JDK Version: 1.8.0_101),如果这时候BitSet().set(64),它会自动扩容至当前容量的翻倍,也就是*2,在这即0~127。
就先写到这,2016年10月22日16:56:01。课后习题部分是很依赖对前文的理解,且变化不是太大,书后答案代码部分大都是用C/C++写的,但只会Java的我看起来也不麻烦(看到qsort好羡慕C系的程序员啊),明天看看有没有有意思的题目再补充吧。#明日债明日还#
;-)
【读书笔记】《编程珠玑》第一章之位向量&位图的更多相关文章
- 编程珠玑第一章的算法,Java实现,通俗易懂
该算法也就是所谓的位图算法,用一个int表示32位,也就是实际值为1~32的数. 按照书里说的, 该算法只适合内存有限,而磁盘和时间不限,且数字在1~MAX之间不重复的排序. package demo ...
- 读书笔记http之第一章
http TCP/IP协议各层: 应用层 决定了向用户提供应用服务时通信的活动. 比如 : FTP(FileTransferProtocol,文件传输协议)和DNS(DomainNameSystem, ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)
SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...
- 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系
本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...
- JavaScript DOM编程艺术第一章:JavaScript简史
本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助, ...
- 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程
第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...
- [书籍翻译] 《JavaScript并发编程》第一章 JavaScript并发简介
> 本文是我翻译<JavaScript Concurrency>书籍的第一章,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并 ...
- [Java编程思想] 第一章 对象导论
第一章 对象导论 "我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来--除非赞成这个协定中规定的有 ...
随机推荐
- json和jsonp
JSON是一种数据交换格式! JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议! 一般使用JSON来传数据,靠JSONP来跨域. JSON的优点: 1.基于纯文本, ...
- No.23
腓利比书3:19:"他们的结局就是沉沦,他们的神就是自己的肚腹,他们以自己的羞辱为荣耀,专以地上的事为念". 谨记!
- Web Config配置备忘
数据压缩 <httpCompression>节点用于配置静态压缩和动态压缩,<urlCompression>则用于开关 http压缩 <urlCompression do ...
- 55. 2种方法求字符串的组合[string combination]
[本文链接] http://www.cnblogs.com/hellogiser/p/string-combination.html [题目] 题目:输入一个字符串,输出该字符串中字符的所有组合.举个 ...
- OnlineTV 电视播放工具
通过网络使用电脑收看电视节目的播放工具,跟其他播放软件不同的是增加了录制功能. getList_bin_src.7z 获取电视直播源 OnlineTV-20161005.tar.xz OnlineTV ...
- Cnblogs自定义皮肤css样式-星空观测者
不知不觉来Cnblogs也这么久了,然而Blogs提供的主题还是依旧那么复古,总觉得阅读起来难免枯燥,虽然我认为做技术不可以太过浮躁,但是一个美观的主题终究是吸引人眼的第一要素. 毕竟这么久了,在博客 ...
- 463. Island Perimeter
https://leetcode.com/problems/island-perimeter/ 在一个N×N的矩阵中,N<100,1代表岛,0代表海,岛内没有海,求岛的周长 [[0,1,0,0] ...
- RecyclerView解密篇(二)
在上一篇(RecyclerView解密篇(一))文章中简单的介绍了RecyclerView的基本用法,接下来要来讲讲RecyclerView的更多用法,要实现不同的功能效果,大部分都还是在于Recyc ...
- MVC Code First 当实体类发生变化时,如何自动更新数据库表
下面做一个例子,Category是用户新建的一个实体类,然后添加一个字段,然后让数据库中的Category表也添加一个字段 1.Category.cs
- [Android Pro] Android开发实践:自定义ViewGroup的onLayout()分析
reference to : http://www.linuxidc.com/Linux/2014-12/110165.htm 前一篇文章主要讲了自定义View为什么要重载onMeasure()方法( ...