上一页 1 ··· 36 37 38 39 40 41 42 43 44 ··· 46 下一页
摘要: 图论在数据结构中是非常有趣而复杂的,作为web码农的我,在实际开发中一直没有找到它的使用场景,不像树那样的频繁使用,不过还是准备仔细的把图论全部过一遍。一:最小生成树 图中有一个好玩的东西叫做生成树,就是用边来把所有的顶点联通起来,前提条件是最后形成的联通图中不能存在回路,所以就形成这样一个推理:假设图中的顶点有n个,则生成树的边有n-1条,多一条会存在回路,少一路则不能把所有顶点联通起来,如果非要在图中加上权重,则生成树中权重最小的叫做最小生成树。对于上面这个带权无向图来说,它的生成树有多个,同样最小生成树也有多个,因为我们比的是权重的大小。二:Prim算法求最小生成树的算法有很多... 阅读全文
posted @ 2012-12-12 19:12 一线码农 阅读(7852) 评论(6) 推荐(3)
摘要: 赫夫曼树又称最优二叉树,也就是带权路径最短的树,对于赫夫曼树,我想大家对它是非常的熟悉,也知道它的应用场景,但是有没有自己亲手写过,这个我就不清楚了,不管以前写没写,这一篇我们来玩一把。一:概念赫夫曼树里面有几个概念,也是非常简单的,先来看下面的图:1. 基础概念<1> 节点的权: 节点中红色部分就是权,在实际应用中,我们用“字符”出现的次数作为权。<2> 路径长度:可以理解成该节点到根节点的层数,比如:“A”到根节点的路径长度为3。<3> 树的路径长度:各个叶子节点到根节点的路径长度总和,用WPL标记。最后我们要讨论的的赫夫曼树也就是带权路径长度最小的一棵 阅读全文
posted @ 2012-12-09 14:27 一线码农 阅读(7407) 评论(5) 推荐(7)
摘要: 这一篇我们来看树状数组的加强版线段树,树状数组能玩的线段树一样可以玩,而且能玩的更好,他们在区间求和,最大,平均等经典的RMQ问题上有着对数时间的优越表现。一:线段树 线段树又称"区间树”,在每个节点上保存一个区间,当然区间的划分采用折半的思想,叶子节点只保存一个值,也叫单元节点,所以最终的构造就是一个平衡的二叉树,拥有CURD的O(lgN)的时间。从图中我们可以清楚的看到[0-10]被划分成线段的在树中的分布情况,针对区间[0-N],最多有2N个节点,由于是平衡二叉树的形式也可以像堆那样用数组来玩,不过更加耗费空间,为最多4N个节点,在针对RMQ的问题上,我们常常在每个节点上增加一 阅读全文
posted @ 2012-12-08 00:37 一线码农 阅读(4720) 评论(3) 推荐(2)
摘要: 在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美,但是在特定的场合下:①:对10亿个不重复的整数进行排序。②:找出10亿个数字中重复的数字。当然我只有普通的服务器,就算2G的内存吧,在这种场景下,我们该如何更好的挑选数据结构和算法呢?一:问题分析 这年头,大牛们写的排序算法也就那么几个,首先我们算下放在内存中要多少G: (10亿 * 32)/(1024*1024*1024*8)=3.6G,可怜的2G内存直接爆掉,所以各种神马的数据结构都玩不起来了,当然使用外排序还是可以解决问题的,由于要走IO所以暂时剔除,因为... 阅读全文
posted @ 2012-12-06 12:59 一线码农 阅读(19388) 评论(30) 推荐(20)
摘要: 有一种数据结构是神奇的,神秘的,它展现了位运算与数组结合的神奇魅力,太牛逼的,它就是树状数组,这种数据结构不是神人是发现不了的。一:概序 假如我现在有个需求,就是要频繁的求数组的前n项和,并且存在着数组中某些数字的频繁修改,那么我们该如何实现这样的需求?当然大家可以往真实项目上靠一靠。① 传统方法:根据索引修改为O(1),但是求前n项和为O(n)。②空间换时间方法:我开一个数组sum[],sum[i]=a[1]+....+a[i],那么有点意思,求n项和为O(1),但是修改却成了O(N),这是因为我的Sum[i]中牵 涉的数据太多了,那么问题来了,我能不能在相应的... 阅读全文
posted @ 2012-12-05 12:50 一线码农 阅读(7596) 评论(22) 推荐(8)
摘要: 前端时间玩小爬虫的时候,我把url都是放在内存队列里面的,有时我们在抓取url的时候,通过LCS之类的相似度比较,发现某些url是很重要的,需要后端解析服务器优先处理,针对这种优先级比较大的url,普通的队列还是苦逼的在做FIFO操作,现在我们的需求就是优先级大的优先服务,要做优先队列,非堆莫属。一:堆结构 1:性质 堆是一种很松散的序结构树,只保存了父节点和孩子节点的大小关系,并不规定左右孩子的大小,不像排序树那样严格,又因为堆是一种完全二叉树,设节点为i,则i/2是i的父节点,2i是i的左孩子,2i+1是i的右孩子,所以在实现方式上可以采用轻量级的数组。2:用途 如果大家玩过微... 阅读全文
posted @ 2012-12-03 16:33 一线码农 阅读(8467) 评论(4) 推荐(4)
摘要: 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题。当然你也可以用KMP算法求出,那么它的时间复杂度为O(c*(m+n)),c:为模式串的个数。m:为模式串的长度,n:为正文的长度,那么这个复杂度就不再是线性了,我们学算法就是希望能把要解决的问题优化到极致,这不,AC自动机就派上用场了。 其实AC自动机就是Trie树的一个活用,活用点就是灌输了kmp的思想,从而再次把时间复杂度优化到线性的O(N),刚好我前面的文章已经说过了Trie树和KMP,这里还是默认大家都懂。一:构建AC自动机同样我也用网上的经典例子,现有say sh.. 阅读全文
posted @ 2012-12-02 16:11 一线码农 阅读(9518) 评论(3) 推荐(10)
摘要: 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的,确实kmp算法还是有点饶人的,如果说红黑树是变态级的,那么kmp算法比红黑树还要变态,很抱歉,每次打kmp的时候,输入法总是提示“看毛片”三个字,嘿嘿,就叫“看毛片算法”吧。一:BF算法 如果让你写字符串的模式匹配,你可能会很快的写出朴素的bf算法,至少问题是解决了,我想大家很清楚的知道它的时间复杂度为O(MN),原因很简单,主串和模式串失配的时候,我们总是将模式串的第一位与主串的下一个字符进行比较,所以复杂度高在主串每次失配的时候都要回溯,图我就省略了。二:KMP算法 刚才我们... 阅读全文
posted @ 2012-12-01 01:57 一线码农 阅读(14737) 评论(8) 推荐(4)
摘要: 很有段时间没写此系列了,今天我们来说Trie树,Trie树的名字有很多,比如字典树,前缀树等等。一:概念 下面我们有and,as,at,cn,com这些关键词,那么如何构建trie树呢?从上面的图中,我们或多或少的可以发现一些好玩的特性。 第一:根节点不包含字符,除根节点外的每一个子节点都包含一个字符。 第二:从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。 第三:每个单词的公共前缀作为一个字符节点保存。二:使用范围 既然学Trie树,我们肯定要知道这玩意是用来干嘛的。 第一:词频统计。 可能有人要说了,词频统计简单啊,一个hash或者一个... 阅读全文
posted @ 2012-11-25 22:30 一线码农 阅读(112815) 评论(17) 推荐(40)
摘要: 相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,“商品推荐”,"猜你喜欢“,在实体店中我们有导购来为我们服务,在网络上我们需要同样的一种替代物,如果简简单单的在数据库里面去捞,去比较,几乎是完成不了的,这时我们就需要一种协同推荐算法,来高效的推荐浏览者喜欢的商品。一:概念 SlopeOne的思想很简单,就是用均值化的思想来掩盖个体的打分差异,举个例子说明一下:在这个图中,系统该如何计算“王五“对”电冰箱“的打分值呢?刚才我们也说了,slopeone是采用均值化的思想,也就是:R王五=4-{[(5-10)+(4-5)]/2}=7 。下面我们看看多于两项的商品,如. 阅读全文
posted @ 2012-11-22 14:43 一线码农 阅读(11185) 评论(12) 推荐(6)
摘要: 这篇我们看看最长公共子序列的另一个版本,求字符串相似度(编辑距离),我也说过了,这是一个非常实用的算法,在DNA对比,网页聚类等方面都有用武之地。一:概念 对于两个字符串A和B,通过基本的增删改将字符串A改成B,或者将B改成A,在改变的过程中我们使用的最少步骤称之为“编辑距离”。比如如下的字符串:我们通过种种操作,痉挛之后编辑距离为3,不知道你看出来了没有?二:解析 可能大家觉得有点复杂,不好理解,我们试着把这个大问题拆分掉,将"字符串 vs 字符串“,分解成”字符 vs 字符串“,再分解成”字符 vs 字符“。<1> ”字符“vs”字符“ 这种情况是最简单的了,比如”A 阅读全文
posted @ 2012-11-11 23:45 一线码农 阅读(11748) 评论(4) 推荐(7)
摘要: 一: 作用 最长公共子序列的问题常用于解决字符串的相似度,是一个非常实用的算法,作为码农,此算法是我们的必备基本功。二:概念 举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出子序列不见得一定是连续的,连续的那是子串。 我想大家已经了解了子序列的概念,那现在可以延伸到两个字符串了,那么大家能够看出:cnblogs和belong的公共子序列吗?在你找出的公共子序列中,你能找出最长的公共子序列吗?从图中我们看到了最长公共子序列为blog,仔细想想我们可以发现其实最长公共子序列的个数不是唯一的,可能会有两个以上,但是长度... 阅读全文
posted @ 2012-11-11 00:55 一线码农 阅读(75963) 评论(20) 推荐(29)
摘要: 这一篇我们聊聊在页面抓取时应该注意到的几个问题。一:网页更新 我们知道,一般网页中的信息是不断翻新的,这也要求我们定期的去抓这些新信息,但是这个“定期”该怎么理解,也就是多长时间需要抓一次该页面,其实这个定期也就是页面缓存时间,在页面的缓存时间内我们再次抓取该网页是没有必要的,反而给人家服务器造成压力。就比如说我要抓取博客园首页,首先清空页面缓存,从Last-Modified到Expires,我们可以看到,博客园的缓存时间是2分钟,而且我还能看到当前的服务器时间Date,如果我再次刷新页面的话,这里的Date将会变成下图中If-Modified-Since,然后发送给服务器,判断浏览器... 阅读全文
posted @ 2012-11-08 01:23 一线码农 阅读(14395) 评论(19) 推荐(12)
摘要: 在ajax横行的年代,很多网页的内容都是动态加载的,而我们的小爬虫抓取的仅仅是web服务器返回给我们的html,这其中就跳过了js加载的部分,也就是说爬虫抓取的网页是残缺的,不完整的,下面可以看下博客园首页从首页加载中我们看到,在页面呈现后,还会有5个ajax异步请求,在默认的情况下,爬虫是抓取不到这些ajax生成的内容的,这时候要想获取就必须调用浏览器的内核引擎来下载这些动态页面,目前内核引擎三足鼎立。Trident: 也就是IE内核,WebBrowser就是基于该内核,但是加载性内比较差。Gecko: FF的内核,性能相对Trident较好。WebKit: Safari和Chrome... 阅读全文
posted @ 2012-11-06 00:00 一线码农 阅读(36701) 评论(23) 推荐(5)
摘要: 第一篇我们做了一个简单的页面广度优先来抓取url,很显然缺点有很多,第一:数据结构都是基于内存的,第二:单线程抓取速度太慢,在实际开发中肯定不会这么做的,起码得要有序列化到硬盘的机制,对于整个爬虫架构来说,构建好爬虫队列相当重要。 先上一幅我自己构思的架构图,不是很完善,算是一个雏形吧。一:TODO队列和Visited集合 在众多的nosql数据库中,mongodb还是很不错的,这里也就选择它了,做集群,做分片轻而易举。二:中央处理器 群架,斗殴都是有带头的,那中央处理器就可以干这样的事情,它的任务很简单, 第一: 启动时,根据我们定义好的规则将种子页面分发到各个执行服务器。 第... 阅读全文
posted @ 2012-11-04 18:51 一线码农 阅读(9919) 评论(12) 推荐(12)
上一页 1 ··· 36 37 38 39 40 41 42 43 44 ··· 46 下一页