一种节省内存的lcs算法的制作方法

文档序号:6422881阅读:263来源:国知局
专利名称:一种节省内存的lcs算法的制作方法
技术领域
本发明涉及两个序列的比较算法,具体说是一种节省内存的LCS算法。所述LCS 是指最大共同子序列(最长公共子序列hLongestCommon Subsequence。可广泛应用于文本比较、图形相似处理、计算生物学等领域。
背景技术
LCS(Longest Common Subsequence)算法是计算机科学领域比较经典的算法,用来比较序列的相似程度,具体说是用来寻找多个序列(一般是两个)最长公共子序列的一种算法。LCS算法本申请不做详细介绍(可参考http://www. ics. uci. edu/ eppstein/161/960229. html)。这种算法消耗内存的多少跟序列的长度有关,如图7所示, 是其算法的一部分。由图7中带下划线的文字部分可见,LCS算法会用一个二维数组C来存储两个序列在比较过程中的状态。以字符串这种典型的序列为例,两个字符串NemAtode kNOwledge, empty bottle,它们的公共序列是“emtole”,如图1所示。LCS算法会用二维数组来记录状态,如图2所示。显然,如果第一个字符串长度为 m,第二个字符串长度为n,这里二维数组需要内存为sizeof (int) * (m+1) * (n+1)。如果m和 η为2万,这里需要耗费的内存将近1600ΜΒ,如果为10万,需要耗费的内存将近40GB。在实际应用中,我们想比较两个源代码文件(这里把行看作一个序列节点),几万行的文件也比较常见,用目前的这种耗费巨大内存算法不太现实(IBM的Java IDE开发环境Eclipse默认的比较文件的大小上限为1MB)。所以,必须要想办法来减少这个二维数组的内存。实际上,如图2所示,该数组有好多地方存的数字都是一样的,后来有人改进了这个算法,数组里面的数字只有两种0和1,1表示数字跟前面的不同,O表示跟前面的相同。这样,数组可以声明为bool (布尔)类型的二维数组,需要的内存为 sizeof (bool)*(m+1)*(n+1),只有之前的1/4。所述改进后将数组声明为bool (布尔)类型的LCS算法流程图如图3. a、3. b所示。图3. a为整个LCS算法的流程,图3. b为图3. a所示LCS算法中“m*n嵌套循环给 arrCon各个数据位赋值”这个步骤的细化。改进之后通过增加代码复杂度达到了减少内存占用的目的。图3.a、3.b所示算法的核心思想是通过一个二维布尔数组arrC0n[m,n]作为临时变量存储序列比较过程中的状态,然后通过循环遍历得出两个序列的公共子序列。随着计算量的增加,LCS算法中布尔值的存取也出现了消耗内存大的问题。为进一步减少内存的占用,此种改进算法有必要进一步优化。还能不能进一步减少这个二维布尔数组arrCon[m,η]的内存呢?表面上看,bool 类型只占一个字节,不能再减少了。实际上,我们知道计算机是用O和1来存储数据的,一个字节(Byte)有8位(bit)。用一个字节也就是8个位来存储一个O或者1似乎有些浪费。如果语言能提供位(bit)这种数据类型就好了,用这种类型定义的数组,理论上这个数组所消耗的内存只有最初int数组的1/32。以C/C++为例,C/C++本身没有提供位(bit)这种数据类型,不过我们可以定义结构体sbyte来访问位。如图4所示。用Sizeof(Sbyte)检查一下,运算结果确实是1。假设我们原来要定义一个m行η列的bool数组,现在以结构体sbyte为基础,就可以只用定义m*n/8的一维整形数组sbyte []arMatriX(参见图5所示的C/C++位直接存储)。由于新数组arMatrix是对位进行存取,即数组上每个元素可以存储8个布尔值,所以整个数组arMatrix仍可以存储m*n个布尔值。目前市面上有多种文本比较工具(如VDiff和Compare It!)就是利用这一特性。不过这种做法有它的局限性,即这种结构体其他语言有可能无法实现,如C#、Java等。

发明内容
针对现有技术中存在的缺陷,本发明的目的在于提供一种节省内存的LCS算法, 同样可以使内存消耗只有原来的1/32,而且同时适用于绝大部分编程语言。为达到以上目的,本发明采取的技术方案是一种节省内存的LCS算法,其特征在于用一个一维整形数组存储两个序列在比较过程中的比较状态数据;第一个序列长度为m,第二个序列长度为n,所述比较状态数据为布尔值,比较状态数据共m*n个,存储比较状态数据的一维整形数组为一个一维的m*n/32的整形数组;在向该一维整形数组内存储比较状态数据时,用位运算存储实现对该一维整形数组的存储,每一位存储一个比较状态数据;在从该一维整形数组内读取比较状态数据时,用位运算读取实现对该一维整形数组的读取。在上述技术方案的基础上,当需要存储比较状态数据时,包括以下步骤步骤1,计算整形int所占位数;步骤2,声明一个一维整形数组arMatrix ;步骤3,确定第i行j列元素在一维数组的第几(index)列;步骤4,确定第i行j列元素在第index列数据的第几(offset)位;步骤5,生成一个第offset位数据为true的数offsetData ;步骤6,将 true 值存储到第 index 列数据arMatrix [index] | = offsetData。在上述技术方案的基础上,当需要读取比较状态数据时,包括以下步骤步骤1,声明布尔变量bVal ;步骤2,确定第i行j列元素在一维数组的第几(index)列;步骤3,确定第i行j列元素在第index列数据的第几(offset)位;步骤4,生成一个第offset位数据为true的数offsetData ;步骤5,进行与运算并返回运算结果结果为0代表一维数组第offset位数据为 0,否则代表一维数组第offset位数据为1。本发明所述的节省内存的LCS算法,同样可以使内存消耗只有普通算法的1/32, 该算法适用于绝大部分编程语言。


本发明有如下附图图1两个字符串的公共序列的示例,图2记录状态的二维数组的示例,图3. a改进后将数组声明为bool (布尔)类型的LCS算法流程图,图3. b图3中“m*n嵌套循环给arrCon各个数据位赋值”这个步骤的细化,图4定义结构体的示例,图5传统做法、C/C++位直接存储、位运算存储的流程图对比,图6传统做法、C/C++位直接读取、位运算读取的流程图对比,图7LCS算法的一部分。
具体实施例方式以下结合附图对本发明作进一步详细说明。本发明的目的之一就是利用位运算进行布尔值的按位存取方式来实现减少LCS 算法内存的占用。我们知道,在主流的计算机语言里,都有位运算。下表是位运算的运算符及其含义
权利要求
1.一种节省内存的LCS算法,其特征在于用一个一维整形数组存储两个序列在比较过程中的比较状态数据;第一个序列长度为m,第二个序列长度为n,所述比较状态数据为布尔值,比较状态数据共m*n个,存储比较状态数据的一维整形数组为一个一维的m*n/32的整形数组;在向该一维整形数组内存储比较状态数据时,用位运算存储实现对该一维整形数组的存储,每一位存储一个比较状态数据;在从该一维整形数组内读取比较状态数据时,用位运算读取实现对该一维整形数组的读取。
2.如权利要求1所述的节省内存的LCS算法,其特征在于,当需要存储比较状态数据时,包括以下步骤步骤1,计算整形int所占位数;步骤2,声明一个一维整形数组arMatrix ;步骤3,确定第i行j列元素在一维数组的第index列;步骤4,确定第i行j列元素在第index列数据的第offset位;步骤5,生成一个第offset位数据为true的数offsetData ;步骤 6,将 true 值存储到第 index 列数据arMatrix [index] | = offsetData。
3.如权利要求1所述的节省内存的LCS算法,其特征在于,当需要读取比较状态数据时,包括以下步骤步骤1,声明布尔变量bVal ;步骤2,确定第i行j列元素在一维数组的第index列; 步骤3,确定第i行j列元素在第index列数据的第offset位; 步骤4,生成一个第offset位数据为true的数offsetData ; 步骤5,进行与运算并返回运算结果结果为0代表一维数组第offset位数据为0,否则代表一维数组第offset位数据为1。
全文摘要
本发明涉及一种节省内存的LCS算法,用一个一维整形数组存储两个序列在比较过程中的比较状态数据;第一个序列长度为m,第二个序列长度为n,所述比较状态数据为布尔值,比较状态数据共m*n个,存储比较状态数据的一维整形数组为一个一维的m*n/32的整形数组;在向该一维整形数组内存储比较状态数据时,用位运算存储实现对该一维整形数组的存储,每一位存储一个比较状态数据;在从该一维整形数组内读取比较状态数据时,用位运算读取实现对该一维整形数组的读取。本发明所述的节省内存的LCS算法,可以使内存消耗只有普通算法的1/32,该算法适用于绝大部分编程语言。
文档编号G06F17/22GK102184165SQ201110101299
公开日2011年9月14日 申请日期2011年4月22日 优先权日2011年4月22日
发明者万金利, 何永刚, 徐艳芬 申请人:烽火通信科技股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1