`
nlslzf
  • 浏览: 1049092 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

算法的力量:位运算在排序与搜索中的应用【转】

阅读更多

http://www.cnblogs.com/Geometry/archive/2009/04/11/1433679.html  

楔子: 问题:假设一个文件中有9亿条不重复的9位整数,现在要求对这个文件进行排序。

一般解题思路: 1、将数据导入到内存中 2、将数据进行排序 (比如插入排序、快速排序) 3、将排序好的数据存入文件

难题: 一个整数为4个字节即使使用数组也需要900,000,000 * 4byte = 3.4G内存对于32位系统,访问2G以上的内存非常困难,而且一般设备也没有这么多的物理内存将数据完全导入到内存中的做法不现实。

其他解决办法: 1、导入数据库运算 2、分段排序运算 3、使用bit位运算

解决方案一:数据库排序 将文本文件导入到数据库,让数据库进行索引排序操作后提取数据到文件

优点:操作简单缺点:运算速度慢,而且需要数据库设备。

解决方案二:分段排序 操作方式:规定一个内存大小,比如200M,200M可以记录52428800条记录,我们可以每次提取5000万条记录到文件进行排序,要装满9位整数需要20次,所以一共要进行20次排序,需要对文件进行20次读操作

缺点: 编码复杂,速度也慢(至少20次搜索)

关键步骤:先将整个9位整数进行分段,亿条数据进行分成20段,每段5000万条,在文件中依次搜索0~5000万,50000001~1亿…… 将排序的结果存入文件

解决方案三:bit位操作 思考下面的问题: 一个最大的9位整数为999999999 这9亿条数据是不重复的,可不可以把这些数据组成一个队列或数组,让它有0~999999999(10亿个)元素数组下标表示数值,节点中用0表示这个数没有,1表示有这个数,判断0或1只用一个bit存储就够了

声明一个可以包含9位整数的bit数组(10亿),一共需要10亿/8=120M内存,把内存中的数据全部初始化为0 ,读取文件中的数据,并将数据放入内存。比如读到一个数据为341245909这个数据,那就先在内存中找到341245909这个bit,并将bit值置为1 ,遍历整个bit数组,将bit为1的数组下标存入文件

关键代码 检查是某一个char里面(first)的第second位中存储的数据是否为1

bool CompareBit (unsigned char first, int second)

 {

const static int mark_buf[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};

if (second > 8) return false;

return (first & mark_buf[second]) == mark_buf[second];

 }

将某一个char(Desc)中的第source位置为1

bool WriteToBit (unsigned char *Desc, int source)

{

const static int mark_buf[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};

if (source > 8) return false;

Desc[0] |= mark_buf[source];

return true;

}

案例 在某个项目中,我们需要对2亿条手机号码删除重复记录(过滤号码黑名单同样有效)

工作难点就在于如何处理这2亿条电话号码,直接用哈希表存放手机号码不大现实,即使经过优化,用一个unsigned int存放一条记录,那也得需要2亿*4=8亿byte,远超过32位系统的寻址能力

解决方案: 将电话号码由12位单个数字组成的字符串转换为一个unsigned int型数据(这个完全可能,手机号码由前三位数字和后面八位数字组成,后面八位需要占到1~1000万的空间,而前面用0~100的数字存储已经足够) ,为简单起见,默认为0~4G的数字都有可能分布号码,为此我们分配4G/32=512M的内存,将这2亿个号码整理成unsigned int类型后按上述办法存放在这块内存中(比如13512345678我们整理后为112345678,我们找到内存中112345678bit的下标,并将此bit值设为1) ,遍历整个bit数组,记录下所有的号码,这些号码即是不重复的手机号码

总结 建立一个足够大的bit数组当作hash表,以bit数组的下标来表示一个整数,以bit位中的0或1来表示这个整数是否在这个数组中存在,适用于无重复原始数据的搜索,原来每个整数需要4byte空间变为1bit,空间压缩率为32倍,扩展后可实现其他类型(包括重复数据)的搜索

注意 由于操作系统和编程语言本身的限制,有可能内存足够,但无法分配一块连续大内存的情况,这样的话可以申请多块稍微小一点的内存,然后用链表或其他的方式连接起来使用

分享到:
评论

相关推荐

    数据结构算法与应用——C++语言描述英文

    书中可能会包含对诸如堆栈、队列、排序算法、矩阵运算算法等基础数据结构和算法的介绍。第二编程课程会覆盖更多的数据结构和算法,而接下来的一到两个课程通常会专门用来深入研究数据结构和算法。由于课程数量的增加...

    各类算法精讲

    本文将对“各类算法精讲”这一资源集合中的核心算法进行详细介绍,并探讨它们在实际应用中的重要性。 数论算法是算法家族中的数学基础之一。它们在解决涉及整数性质和运算的问题时显得尤为重要。欧几里得算法是数论...

    Cholesky分解递归算法与改进1

    递归算法在计算稠密线性代数问题中的应用展现出独特优势。传统的线性代数计算方法主要依赖于迭代算法,而递归算法能够自动生成适合特定问题和特定计算环境的矩阵分块。这种自动的分块策略能够充分利用现代计算机中...

    algorithm:研究算法

    3. 分类:排序算法(冒泡排序、选择排序、插入排序、快速排序、归并排序等)、搜索算法(线性搜索、二分搜索等)、图算法(Dijkstra最短路径算法、Floyd-Warshall算法等)和动态规划等。 二、C++与算法 1. C++作为...

    计算机程序设计艺术(共3卷)

    此外,搜索算法也是他关注的重点,比如线性搜索与二分搜索的应用场景和效率对比。递归作为一种强大的编程技巧,同样在这一卷中得到了充分的讨论,Knuth不仅解释了递归的工作原理,还指出递归在解决某些问题时的独特...

    有关数论的算法.doc

    这些数论算法不仅理论性强,而且在实际应用中具有广泛的影响力,从信息安全到工程设计,数论的智慧无处不在。通过深入理解和掌握这些算法,我们可以更好地理解和利用数学的力量去解决现实世界中的问题。

    2014noip复赛提高组 测试数据

    1. **基础算法**:排序(如快速排序、归并排序)、搜索(如二分查找、深度优先搜索、广度优先搜索)、图论算法(如最短路径、最小生成树)等。 2. **数据结构**:数组、链表、栈、队列、哈希表、树(如二叉树、平衡...

    北大OJ试题集

    1. **排序与搜索**:如快速排序、归并排序、二分查找等经典算法,这些是基础中的基础,也是解决很多复杂问题的基石。 2. **动态规划**:动态规划是一种用于求解最优化问题的方法,通过将大问题分解为子问题,然后...

    (word完整版)计算机二级公共基础知识.doc

    在搜索引擎中,算法能够快速对网页进行排序,提供准确的搜索结果。 因此,对于IT专业人员而言,深入理解和熟练掌握数据结构与算法的基本概念是必不可少的。这不仅要求他们具备扎实的理论知识,更要求他们能够在实际...

    谷歌黑板报

    这通常涉及词频逆文档频率(TF-IDF)、PageRank等算法,通过数学模型评估关键词在网页中的重要性和网页在整个网络中的权威性,从而给出合理的排序。 #### 知识点十:有限状态机与地址识别 有限状态机(FSM)是一种...

    全国计算机等级考试公共基础知识四.pdf

    二叉树有许多特殊形式,如二叉搜索树、完全二叉树和平衡二叉树等,它们在数据库、排序和搜索等方面有着重要的应用。 全国计算机等级考试的公共基础知识四部分,不仅要求考生理解这些基本概念,还要掌握它们的应用。...

    量子计算理论与实现(英文版)

    - **量子优势**:量子计算能够在某些特定任务上显著优于经典计算,例如因子分解和搜索未排序数据库。 - **实际应用**:讨论了量子计算在密码学、化学模拟、优化问题等领域中的潜在应用。 综上所述,《量子计算:...

    831程序设计与数据结构大纲1

    6. **指针**:指针是C语言的强大力量,考生需理解指针的定义、运算和应用,包括指针与数组、函数的关系,以及指针数组和多级指针的使用。 7. **结构体、共用体和枚举类型**:这些自定义数据类型使得可以组合多种...

    【公务员】计算机二级公共基础知识.pdf

    特别地,二叉树是树的一种特例,每个结点最多有两个子结点,这使得二叉树在计算机科学中有着广泛的应用,特别是在实现各种搜索、排序算法时。 掌握上述数据结构与算法的知识,对于公务员而言具有重要意义。在信息化...

    福建省福州市八县(市)协作校 高二数学下学期期中联考试题 文 试题.doc

    解答题:这部分主要涉及复数运算、函数性质、数列的归纳证明、统计分析的线性回归、数列的“分裂”规律、函数极值点的判定以及不等式性质的应用,需要具体解题步骤和计算,不适合在这里详细展开。 以上知识点涵盖...

    全国计算机等级考试二级公共基础知识点.doc

    在当今信息化时代,计算机技术无处不在,成为推动社会进步的重要力量。为了适应这一趋势,培养具有扎实计算机基础知识的人才显得尤为重要。全国计算机等级考试作为衡量计算机应用能力的重要标准之一,其中二级公共...

    2015 小米校园招聘笔试题

    同时,算法分析也是重点,包括排序(如冒泡排序、快速排序、归并排序等)、查找(如二分查找、哈希查找)和图的遍历算法(如深度优先搜索、广度优先搜索)等。 四、操作系统 操作系统部分可能涉及进程与线程的概念...

    《数据结构——C语言描述(第二版)》第二版全套电子课件完整版ppt整本书电子讲义最全教学教程整套课件.ppt

    如排序算法、搜索算法等,都有对应的数据结构与之匹配,以达到最佳的性能表现。 此外,作者也强调了C语言在数据结构教学和应用中的重要性。C语言以其接近硬件、执行效率高、功能强大等特性,成为学习和实现数据结构...

    Dimik-Oj-Problem-Solutions:在数学和计算机科学中,算法是定义明确的,计算机可实现的指令的有限序列,通常用于解决一类问题或执行计算

    在信息技术的广阔领域中,算法扮演着核心角色,它是数学与计算机科学的交汇点,是解决问题的关键工具。"Dimik-Oj-Problem-Solutions"项目,正是这样一个以算法为中心,通过Python编程语言来实现和解决各类问题的资源...

Global site tag (gtag.js) - Google Analytics