随笔分类 -  算法

主要写一些平时遇到的有趣的算法问题
摘要:前言 在我们日常应用中,应该遇到不少类似的状况: 写文档时,单词拼写错误后,工具自动推荐一个相似且正确的拼写形式; 使用搜狗输入法时,敲错某个字的拼音照样能够打出我们想要的汉字; 利用搜索引擎进行搜索时,下拉框中自动列出与输入相近的词语。 等等,不一一列举。 这种功能是如何实现的呢?里面用到了哪些算 阅读全文
posted @ 2018-09-05 08:35 haolujun 阅读(4374) 评论(13) 推荐(17) 编辑
摘要:前言 我最近一直在公司做检索性能优化。当我看到这个算法之前,我也不认为我负责的检索系统性能还有改进的余地。但是这个算法确实太牛掰了,足足让服务性能提高50%,我不得不和大家分享一下。其实前一段时间的博客中也写到过这个算法,只是没有细讲,今天我准备把它单独拎出来,说道说道。说实话,本人数学功底一般,算 阅读全文
posted @ 2018-08-24 09:39 haolujun 阅读(13763) 评论(52) 推荐(41) 编辑
摘要:背景 最近工作中遇到了一个问题:如何对大规模题库去重?公司经过多年的积累,有着近亿道题目的题库,但是由于题目来源不一导致题库中有很多重复的题目,这些重复的题目在检索时,除了增加搜索引擎的计算量外,并不会提高准确率。此外由于题目过多,搜索引擎往往采取了截断策略,只对一部分题目进行计算,这导致了某些正确 阅读全文
posted @ 2018-02-09 18:10 haolujun 阅读(7747) 评论(19) 推荐(40) 编辑
摘要:前言 工作以后很少用到算法,时间长了脑袋也不灵活。但是最近,我有幸在工作中又开始用到算法,这使我欣喜若狂,这两个算法主要用在计算文本相似度的场景中。小伙伴看标题中的“最长公共子序列”和“最小编辑距离”算法想当然都认为是烂大街的算法了,有什么好讲的。当然那种朴素的$ O(N^{2}) $的算法本文不去 阅读全文
posted @ 2017-12-20 16:59 haolujun 阅读(3592) 评论(2) 推荐(2) 编辑
摘要:前言 对于跳表,我想大家都不陌生吧,这里不多解释,感兴趣的小伙伴可以看我的这篇文章:http://www.cnblogs.com/haolujun/archive/2012/12/24/2830683.html。 这段时间在做我们拍搜的优化,今天我就讲讲我是如何用跳表优化检索系统的。 搜索引擎的夹角 阅读全文
posted @ 2017-12-11 09:48 haolujun 阅读(3086) 评论(0) 推荐(3) 编辑
摘要:前言 最近工作中需要写一个算法,而写完这个算法我却发现了一个很有意思的事情。需要的这个算法是这样的:对于A,B两个字符串,找出最多K个公共子串,使得这K个子串长度和最大。百度之没有这样的算法,然后就开始想了一些乱七八糟的想法,一一被自己举反例推翻了,直到最后找到了正确算法,我觉得这个思考过程值得记录 阅读全文
posted @ 2016-09-11 17:26 haolujun 阅读(762) 评论(0) 推荐(0) 编辑
摘要:S=a + (a + 1) + (a + 2) + ...... + b(其中a, b > 0)现在我们要求,给定一个正整数S,求有多少种不同的,使得上述的等式成立。这个问题很有意思,我猜大家一定想出了比较简单的那个方法了。方法1:代码大概是这个样子的:int sum = 0;for(int st = 1, ed = 1; ed y。1: x = 5, y = 4 => a = 1 b = 4 即10=1+2+3+42: x = 20, y = 1 => a = 10 b= 10. 即10=10S=152S=30=2*3*5,所以满足S=a + (a + 1) + (a + 阅读全文
posted @ 2014-01-26 15:54 haolujun 阅读(1276) 评论(0) 推荐(0) 编辑
摘要:这两天遇到这么一个问题,就是查找一个IP的归属地。当然我会有一个IP段的分配列表,格式如下:16777472 16778239 XX省 XX市第一列是IP段的起始IP,第二列是IP段的终止IP,第三列是对应的省份。一共大概200万条左右。那么好了,如何进行查找呢?想到的最简单的办法,就是二分查找。首先对这些IP段进行首位相接的排序,之后一个二分查找。那么有没有比这个还快的方法呢?我们分析一下上面的二分查找的一个缺点就是,要在所有的IP段上进行二分查找,大概要查找log(2000000)次才能找到一个IP的归属地。那么我们一个自然的想法就是缩小二分的IP段的数量。可以这样做:根据IP的前两个字节 阅读全文
posted @ 2013-08-22 11:27 haolujun 阅读(3384) 评论(0) 推荐(0) 编辑
摘要:注:本文部分内容来源于<<操作系统概念>>第六版,[美]Abraham Silberschatz,Peter Baer Galvin,Greg Gagne著,郑扣根译。如有错误,还望大家批评指正,我先谢过大家了。锁是为了解决某种资源(又有人称临界资源)互斥使用提出的一种机制。常用的有读写锁、互斥锁、自旋锁。接下来就谈谈这个自旋锁。自旋锁和互斥锁功在使用时差不多,每一时刻只能有一个执行单元占有锁,而占有锁的单元才能获得临界资源的使用权,从而达到了互斥的目的。自旋锁与互斥锁的区别在于:自旋锁在执行单元在获取锁之前,如果发现有其他执行单元正在占用锁,则会不停的循环判断锁状态, 阅读全文
posted @ 2013-03-02 15:56 haolujun 阅读(6782) 评论(0) 推荐(0) 编辑
摘要:介绍一个概率检索模型-二值独立模型。这个模型我自认为比较扯淡,如有大神在可以指点一下。这个模型用了N多个假设。假设1:词项之间的出现是相互独立的。这样文档和查询都可以向量化,如下:当词项t出现在文档或查询中,则xt或qt的值为1,否则为0。由于我们假设词项出现是相互独立的,并且向量取值只取0,1两个值,故这个模型就叫做二值独立模型。那么这个模型是如何进行文档检索以及排序的呢,接下来就详细介绍一下。给定一个查询Q,文档D与Q相关的概率可以用P(R=1|(D,Q))表示,不相关的概率可用P(R=0|(D,Q))表示。,。那么我们自然能想到一个可以用来进行排序的指标:P(R=1|(D,Q)),但是实 阅读全文
posted @ 2013-01-14 15:49 haolujun 阅读(3343) 评论(0) 推荐(0) 编辑
摘要:这篇就简单介绍一下搜索引擎的评价方法。从用户的角度去评价一个搜索引擎的检索效果最好的方法就是计算用户在查到自己满意文档时已经浏览的文档数。但是实际中,查询千变万化,文档也千变万化,所以这种方法不可行。人们便提出了下面的概念,并建立了一个评价标准。这里面有三个常用的概念:正确率,精确率,召回率。正确率(Precision,简称为P)定义为:P=返回结果中相关文档个数/返回结果的数目。精确率(accuracy,简称为A)定义为:A=判断结果正确的文档数目/所有文档数目。召回率(Recall,简称为R)定义为: R=返回结果中相关文档数目/所有相关文档数目。实际相关文档数实际不相关文档数返回文档数( 阅读全文
posted @ 2013-01-09 11:17 haolujun 阅读(4611) 评论(0) 推荐(0) 编辑
摘要:相似度从字面上理解就是两个事物的相似程度。在信息检索中,相似度表示的是两个文档之间的相似程度或者查询与文档的相似程度。首先回想一下检索过程:1:首先用户输入查询词。2:搜索引擎根据查询词查找相应的文档。3:搜索引擎把查询结果以一定的方式显示给用户。那么一篇文档是否满足用户的查询需求可以用文本与查询的相似程度来衡量。而相似度到最后总能够计算成一个实数,所以可以根据文档与查询的相似度进行排序。与查询相似度较高的文档排在前面,较低的排在后面。相似度的计算方式五花八门。比如上一篇文章中,可以简单的利用tf*idf的累加和代表文档与查询的相似程度。当然这种方法看上去没什么理论深度,所以就不讨论了。对于一 阅读全文
posted @ 2013-01-08 10:48 haolujun 阅读(4932) 评论(0) 推荐(2) 编辑
摘要:上一篇介绍了倒排表这种数据结构,接下来将介绍一下词频-逆文档频(tf-idf)这个概念。首先,什么是词频?词频就是一篇文档包含一个词的次数。举个例子,如果一篇文档d中“cat”这个词出现了5词,那么我们就说“cat”的词频为5,记做tf(cat)=5。那么,什么是文档频?这个概念也是对于一个词来说的。通俗来说文档频就是包含一个词的文档数目。举个例子,如果有100篇文档都有“cat”这个词,我们就说“cat”的文档频为100,记做df(cat)=100。那么什么叫做逆文档频呢?idf表示逆文档频,检索库中一共有N篇文档,那么idf=log(N/df),例如上例,“cat”的逆文档频记做idf(c 阅读全文
posted @ 2013-01-07 09:38 haolujun 阅读(2106) 评论(0) 推荐(1) 编辑
摘要:这篇就说一个信息检索里面理解最简单的一个东西吧,它就叫做倒排表或者倒排索引。但是这只是个名字,我想大家都知道它是什么就行了,不必纠结于名称。先说说倒排表张什么样子吧!倒排表以词做索引,内容为包含该词的文档编号。对于上图可知,文档1、3、5、7、9包含词"Cat",文档2、5、8、10包含词"Dog"。你可能问这么简单的东西能干啥?其实他就是搜索引擎中的最关键的核心数据结构。那么搜索引擎如何根据用户的查询来找到相关的文档呢?如果用户查询“Cat”,那么只要顺着Cat链把文档1、3、5、7、9返回给用户就行了。如果用户想得到同时包含“Cat”与“Dog“的文 阅读全文
posted @ 2013-01-06 17:11 haolujun 阅读(3838) 评论(3) 推荐(1) 编辑
摘要:前记:本人是一个初学者,新手其实都算不上。没做过信息检索,所以别人怎么做的也不知道。很想知道Google,百度这样的大公司怎么做搜索引擎的,但是没机会也不会知道。凭着自己的理解就写了这么几篇随笔,这样能督促自己思考,也希望得到大神们的指点。这个系列叫做“新手学信息检索”。这个系列说白了,就是把自己看过的东西总结了一下,加入了自己对信息检索一些概念的理解,没什么理论,也不注重于实现,更没有创新。但是当时让我费劲心思才能想明白的东西我会按照自己的意思把它讲出来。不知道自己将会写多少篇,可能总结完一些就会写一些,自己水平有限,概念如果理解有误的话,还请大家拍砖不要拍太狠,在此先谢过了。我想,大家对信 阅读全文
posted @ 2013-01-06 13:55 haolujun 阅读(1947) 评论(1) 推荐(0) 编辑
摘要:摔鸡蛋问题:给你K个鸡蛋,让你测试鸡蛋壳的硬度,测量的方法就是从不同高度的楼层向下扔,如果鸡蛋在第i层摔碎了而在第i-1层没摔碎,那么我们就知道鸡蛋壳的硬度了,即用层数代表鸡蛋壳的硬度。并且假设鸡蛋肯定能用某一层的层数来表示。现在的问题是,用K个鸡蛋,最坏情况下最少需要多少次才能测试出鸡蛋壳的硬度?例如只有一个鸡蛋,那么为了保证在测出鸡蛋壳硬度之前鸡蛋不破裂,只能一层一层的试。如果楼的高度有N层,那么最查情况需要N次实验。如果有两个鸡蛋呢?假设最坏情况最少需要m次实验,那么第一只鸡蛋只能最多在第m层进行实验,如果第m层没有摔碎,那么接下来就必须在第m+m-1层进行实验,如果第m层摔碎了,那么第 阅读全文
posted @ 2012-12-24 11:15 haolujun 阅读(2640) 评论(2) 推荐(3) 编辑
摘要:概率里面经常听到贝叶斯这个词,其实这起源于一个公式:P(B|A) = P(AB)/P(A) = P(B)P(A|B)/P(A),这个公式就是大家所知的贝叶斯公式。其中P(B|A)意思是当A事件发生时,B事件发生的概率。再说这个东西能干什么,其实就是用在模式识别中的分类器设计当中。 模式识别中认为所有的事物都有其一个明确的分类属性。那么我们如何自动的识别一个事物到底是属于何种分类呢?这里面就依仗了概率理论,其中最著名的就是利用上面公式进行分类的贝叶斯分类器。 例如有两个类别W1,W2,对于一个事物A,它到底属于W1还是W2呢? 贝叶斯的决策理论是这么认为的:如果P(W1|A)>... 阅读全文
posted @ 2012-12-23 17:04 haolujun 阅读(480) 评论(0) 推荐(0) 编辑
摘要:假如现在让你随机生成k个范围在1-n内的随机数,那么你能得到多少个不同的随机数呢?刚开始想得时候,我认为当k<=n时,可以得到k个不同的随机数,但是显然这个想法错了。做了个实验在1-1024内随机生成500个数,其中只有394个不同的数,随机生成1000个数,其中有639个不同的数。接下来是很枯燥的数学推导,如果你只是想看看最后的公式,那么就看倒数第二行。如果你想看看推导过程那么就看下去。下面说的东西用到了概率和组合数学中的线性常系数非齐次递推关系。现在我们想求一下,随机生成k个范围在1-n内的随机数,能得到多少个不同的随机数。设我们随机k次得到的的k个数字为x1,x2,......xk 阅读全文
posted @ 2012-11-11 14:06 haolujun 阅读(1165) 评论(0) 推荐(0) 编辑
摘要:大家都遇到过这个问题,就是如何判断一个单链表是否有环?当然,判断方法很多,但是目前网上最出名的那个方法大概是这样:设甲、乙两个指针指向同一起点,之后甲乙交替着走,甲每次走两步,乙每次走一步,遇到下面的情况则说明链表有环:甲某次走完两步后遇到了乙或者乙某次走完一步后遇到了甲。那么大家想没想过,为什么甲每次走两步,乙每次走一步这样可以?如果甲每次走4步乙每次走2步可不可以?各种步长对时间复杂度有什么影响?解释这个问题需要一些点初等数论上的东西,基本上就是欧几里得和丢番图方程的知识。插曲:丢番图方程有解的条件和解的形式假设丢番图方程为ax+by=c,d=gcd(a,b),那么ax+by=c有解的充分 阅读全文
posted @ 2012-10-23 10:42 haolujun 阅读(1380) 评论(2) 推荐(0) 编辑
摘要:最近有同学面试的时候,被问了这么一道题:说有A,B,C三个盒子,其中只有一个盒子里面有宝贝,但是你不知道是哪个盒子。现在你随机的拿过来一个盒子,但是你自己不能看你拿的盒子里是否是宝贝。现在你的对手翻开了剩下的两个盒子中的一个,并且是空盒子,即里面没有宝贝。现在问你:是否要用你手里的盒子去换剩下的那个没有被翻开过的盒子?对于这个问题,可谓是争论不休。有人说不必要换,因为你手里的盒子是宝物的概率现在为1/2,和对手一样。又有一些人说,你手里的盒子是宝物的概率是1/3,而没有翻开的剩下的那个盒子是宝物的概率是2/3。同样一个问题,却有两种解释方法,并且看上去都有道理。那么为什么出现这种情况呢?如果我 阅读全文
posted @ 2012-10-20 09:41 haolujun 阅读(3147) 评论(35) 推荐(1) 编辑