文章分类 - 算法数据结构+acm
摘要://c语言面向对象#include<stdio.h>#include<stdarg.h>#include<stdlib.h>typedef enum {point,circle} shape_type;//两种图形类型,点和圆typedef struct{//定义图像 shape_type type;//图形的标示点和圆 void (*destory)(void *);//销毁图像函数 void (*draw)(void *);//绘制图像函数}shape_t;typedef struct{//点 shape_t common;//类型 int x;//横坐
阅读全文
摘要:http://roba.rushcj.com/?p=540如果有N个集合,求它们之间两两的相似度就需要N*(N-1)/2次计算,当N很大时这个代价仍然承受不起。于是我们需要一种方法能够不遍历所有可能的元素对就找出相似度较大的那些(大于某个给定的阈值t),这就是所谓Locality-Sensitive Hashing。第三章的后半部分基本全是围绕这一话题展开的。这里又要出现一个比较神奇的方法了:由上篇文章所述,对每一列c(即每个集合)我们都计算出了n行minhash值,我们把这n个值均分成b组,每组包含相邻的r=n/b行。对于每一列,把其每组的r个数都算一个hash值出来,把此列的编号记录到ha
阅读全文
摘要:初识A*算法 写这篇文章的初衷是应一个网友的要求,当然我也发现现在有关人工智能的中文站点实在太少,我在这里抛砖引玉,希望大家都来热心的参与。 还是说正题,我先拿A*算法开刀,是因为A*在游戏中有它很典型的用法,是人工智能在游戏中的代表。 A*算法在人工智能中是一种典型的启发式搜索算法,为了说清楚A*算法,我看还是先说说何谓启发式算法。一、何谓启发式搜索算法 在说它之前先提提状态空间搜索。状态空间搜索,如果按专业点的说法就是将问题求解 过程表现为从初始状态到目标状态寻找这个路径的过程。通俗点说,就是在解一个问题时,找到一条解题的过程可以从求解的开始到问题的结果(好象并不通俗 哦)。由...
阅读全文
摘要:字符串匹配(string match)是在实际工程中经常会碰到的问题,通常其输入是原字符串(String)和子串(又称模式,Pattern)组成,输出为子串在原字符串中的首次出现的位置。通常精确的字符串搜索算法包括暴力搜索(Brute force),KMP, BM(Boyer Moore), sunday, robin-karp 以及 bitap。下面分析这几种方法并给出其实现。假设原字符串长度M,字串长度为N。1. Brute force.该方法又称暴力搜索,也是最容易想到的方法。预处理时间 O(0)匹配时间复杂度O(N*M)主要过程:从原字符串开始搜索,若出现不能匹配,则从原搜索位置+..
阅读全文
摘要:《桶排序》中我们能够看到,数据值的范围越大,可能需要桶的个数也就越多,空间代价也就越高。对于上亿单位的关键字,桶排序是很不实用的。基数排序是对桶排序的一种改进,这种改进是让“桶排序”适合于更大的元素值集合的情况,而不是提高性能。多关键字排序问题(类似于字典序):我们先看看扑克牌的例子。一张牌有两个关键字组成:花色(桃<心<梅<方)+面值(2<3<4<...<A)。假如一张牌的大小首先被花色决定,同花色的牌有数字决定的话。我们就有两种算法来解决这个问题。(1) 首先按照花色对所有牌进行稳定排序,这样就可以将所有牌分成4组。然后同组的牌(同花色)再按照面值
阅读全文
摘要:已知一个已经从小到大排序的数组,这个数组中的一个平台(Plateau)就是连续的一串值相同的元素,并且这一串元素不能再延伸。例如,在 1,2,2,3,3,3,4,5,5,6中[1]、[2,2]、[3,3,3]、[4]、[5,5]、[6]都是平台。是编写一个程序,接受一个数组,把这个数组中最长的平台找出 来。在上面的例子中3,3,3就是该数组中最长的平台。【说明】这个程序十分简单,但是要编写好却不容易,因此在编写程序时应该考虑下面 几点:(1) 使用的变量越少越好;(2) 把数组的元素每一个都只查一次就得到结果;(3) 程序语句也要越少越好。这个问题曾经困扰过David Gries 这位知名的计
阅读全文
摘要:LCS:又称最长公共子序列。其中子序列(subsequence)的概念不同于串的子串。它是一个不一定连续但按顺序取自字符串X中的字符序列。例如:串"AAAG"就是串“CGATAATTGAGA”的一个子序列。字符串的相似性问题可以通过求解两个串间的最长公共子序列(LCS)来得到。当然如果使用穷举算法列出串的所有子序列,一共有2^n种,而每个子序列是否是另外一个串的子序列又需要O(m)的时间复杂度,因此这个穷举的方法时间复杂度是O(m*(2^n))指数级别,效率相当的可怕。我们采用动态规划算法来解决这个问题。动态规划算法解决最长公共子序列假如我们有两个字符串:X=[0,1,2.
阅读全文
摘要:LIS:给定一个字符串序列S={x0,x1,x2,...,x(n-1)},找出其中的最长子序列,而且这个序列必须递增存在。下面给出解决这个问题的几种方法:(1) 转化为LCS问题思想:将原序列S递增排序成序列T,然后利用动态规划算法取得S与T的公共最长子序列。具体算法详见《LCS最长公共子序列》。效率:这个方法排序最好的是时间复杂度是O(n*logn),动态规划解决LCS的时间复杂度是O(n^2)。因此总体时间复杂度是O(n*logn)+O(n^2)=O(n^2)级别。(2) 分治策略思想:假设f(i)表示S中 x0 ... xi 子串的最长递增子序列的长度。则有如下递归:找到所有在xi之前,
阅读全文
摘要:模式匹配:在字符串S中,子串P的定位操作通常称做串的模式匹配。说白了,就是在一个字符串中寻找子串。在Suffix Trie和PAT tree中我们已经讨论过匹配子串的方法了。这里我们讨论一种线性匹配算法来寻找子串。例: 我们要在S="ababcabcacbab"中查找子串P="abcac"。下图左侧是一种很普通的模式匹配算法这种普通的模式匹配算法很简单,但时间复杂度是O(n*m)。其中n=S.length,m=T.length. 代价很高。难道真的要像第三趟到第四趟那样:好不容易匹配到S中的第7个位置,但由于不相同,则有回溯到第4个位置重新开始。其实,每
阅读全文
摘要:Suffix Trie:又称后缀Trie或后缀树。它与Trie树的最大不同在于,后缀Trie的字符串集合是由指定字符串的后缀子串构成的。比如、完整字符串"minimize"的后缀子串组成的集合S分别如下: s1=minimize s2=inimize s3=nimize s4=imize s5=mize s6=ize s7=ze s8=e 然后把这些子串的公共前缀作为内部结点构成一棵"minimize"的后缀树,如图所示,其中上图是Trie树的字符表示,下图是压缩表示(详细见《Trie树》)。可见Suffic Trie是一种很适合操作字符串子串的数据结构
阅读全文
摘要:Trie 树,又称字典树,单词查找树。它来源于retrieval(检索)中取中间四个字符构成(读音同try)。用于存储大量的字符串以便支持快速模式匹配。主要应用在信息检索领域。Trie 有三种结构: 标准trie (standard trie)、压缩trie、后缀trie(suffix trie)。最后一种将在《字符串处理4:后缀树》中详细讲,这里只将前两种。1. 标准Trie (standard trie)标准Trie树的结构:所有含有公共前缀的字符串将挂在树中同一个结点下。实际上trie简明的存储了存在于串集合中的所有公共前缀。假如有这样一个字符串集合X{bear,bell,bid,bul
阅读全文
摘要:我们来看一个实际应用。现代搜索技术的发展很多以提供优质、高效的服务作为目标。比如说:baidu、google、sousou等知名全文搜索系统。当我们输入一个错误的query="Jave" 的时候,返回中有大量包含正确的拼写 "Java"的网页。当然这里面用到的技术绝对不会是我们今天讲的怎么简单。但我想说的是:字符串的相似度计算也是做到这一点的方法之一。字符串编辑距离:是一种字符串之间相似度计算的方法。给定两个字符串S、T,将S转换成T所需要的删除,插入,替换操作的数量就叫做S到T的编辑路径。而最短的编辑路径就叫做字符串S和T的编辑距离。举个例子:S=“e
阅读全文
摘要:Patricia Tree 简称PAT tree。它是 trie 结构的一种特殊形式。是目前信息检索领域应用十分成功的索引方法,它是1992年由Connel根据《PATRICIA——Patrical Algorithm to Retrieve Information Coded in Alphanumeric》算法发展起来的。PAT tree 在字符串子串匹配上有这非常优异的表现,这使得它经常成为一种高效的全文检索算法,在自然语言处理领域也有广泛的应用。其算法中最突出的特点就是采用半无限长字串(semi-infinite string 简称 sistring)作为字符串的查找结构。采用半无限长
阅读全文
摘要:C代码#include<stdio.h>#include<malloc.h>typedefstructbinode{chardata;structbinode*lchild;structbinode*rchild;}BiNode,*BiTree;/*****************************输入创建二叉树:abd##ef###c##*其实输入按照先序顺序,#表示叶子节点*****************************/voidcreate(BiTreet){charch=(char)getchar();if(ch=='#'){t-
阅读全文
摘要:从《基于比较的排序结构总结》中我们知道:全依赖“比较”操作的排序算法时间复杂度的一个下界O(N*logN)。但确实存在更快的算法。这些算法并不是不用“比较”操作,也不是想办法将比较操作的次数减少到 logN。而是利用对待排数据的某些限定性假设,来避免绝大多数的“比较”操作。桶排序就是这样的原理。桶排序的基本思想 假设有一组长度为N的待排关键字序列K[1....n]。首先将这个序列划分成M个的子区间(桶)。然后基于某种映射函数,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为N/M的序列)。接着对每个桶B[i]中.
阅读全文
摘要:我们这个专题介绍的动态查找树主要有: 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)。这四种树都具备下面几个优势:(1) 都是动态结构。在删除,插入操作的时候,都不需要彻底重建原始的索引树。最多就是执行一定量的旋转,变色操作来有限的改变树的形态。而这些操作所付出的代价都远远小于重建一棵树。这一优势在《查找结构专题(1):静态查找结构概论》中讲到过。(2) 查找的时间复杂度大体维持在O(log(N))数量级上。可能有些结构在最差的情况下效率将会下降很快,比如BST。这个会在下面的对比中详细阐述。下面我们开始概括性描述这四种树,并相互比较一下优劣。1
阅读全文
摘要:红黑树的性质与定义红黑树(red-black tree)是一棵满足下述性质的二叉查找树:1. 每一个结点要么是红色,要么是黑色。2. 根结点是黑色的。3. 所有叶子结点都是黑色的(实际上都是Null指针,下图用NIL表示)。叶子结点不包含任何关键字信息,所有查询关键字都在非终结点上。4. 每个红色结点的两个子节点必须是黑色的。换句话说:从每个叶子到根的所有路径上不能有两个连续的红色结点5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点黑深度——从某个结点x出发(不包括结点x本身)到叶结点(包括叶子结点)的路径上的黑结点个数,称为该结点x的黑深度,记为bd(x),根结点的黑深度就是该
阅读全文
摘要:当所有的静态查找结构添加和删除一个数据的时候,整个结构都需要重建。这对于常常需要在查找过程中动态改变数据而言,是灾难性的。因此人们就必须去寻找高效的动态查找结构,我们在这讨论一个非常常用的动态查找树——二叉查找树。二叉查找树的特点下面的图就是两棵二叉查找树,我们可以总结一下他的特点:(1) 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值(2) 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值(3) 它的左、右子树也分别为二叉查找树我们中序遍历这两棵树发现一个有序的数据序列: 【1 2 3 4 5 6 7 8 】二叉查找树的操作插入操作:现在我们要查找一个数9,如果不存
阅读全文
摘要:以下文章转载自:http://hxraid.iteye.com/(这个系列的blog不错,包含很多面试算法)在计算机许多应用领域中,查找操作都是十分重要的研究技术。查找效率的好坏直接影响应用软件的性能。比如说:(1) 全文检索技术中对文本建立索引之后,对索引的查找效率将决定搜索引擎的质量。(2) mysql数据库的索引就是B+树结构,查找效率极高。(3) Windows OS的文件系统结构也是采用B+树进行存储的。在《查找算法》系列文章中,我将主要介绍动态查找树结构。其他静态查找结构在下面简单的引出:静态查找:数据集合稳定,不需要添加,删除元素的查找操作。动态查找:数据集合在查找的过程中需要添
阅读全文
浙公网安备 33010602011771号