CN102184165A - 一种节省内存的lcs算法 - Google Patents
一种节省内存的lcs算法 Download PDFInfo
- Publication number
- CN102184165A CN102184165A CN 201110101299 CN201110101299A CN102184165A CN 102184165 A CN102184165 A CN 102184165A CN 201110101299 CN201110101299 CN 201110101299 CN 201110101299 A CN201110101299 A CN 201110101299A CN 102184165 A CN102184165 A CN 102184165A
- Authority
- CN
- China
- Prior art keywords
- array
- dimension
- data
- status data
- storage
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本发明涉及一种节省内存的LCS算法,用一个一维整形数组存储两个序列在比较过程中的比较状态数据;第一个序列长度为m,第二个序列长度为n,所述比较状态数据为布尔值,比较状态数据共m*n个,存储比较状态数据的一维整形数组为一个一维的m*n/32的整形数组;在向该一维整形数组内存储比较状态数据时,用位运算存储实现对该一维整形数组的存储,每一位存储一个比较状态数据;在从该一维整形数组内读取比较状态数据时,用位运算读取实现对该一维整形数组的读取。本发明所述的节省内存的LCS算法,可以使内存消耗只有普通算法的1/32,该算法适用于绝大部分编程语言。
Description
技术领域
本发明涉及两个序列的比较算法,具体说是一种节省内存的LCS算法。所述LCS是指最大共同子序列(最长公共子序列),LongestCommon 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和n为2万,这里需要耗费的内存将近1600MB,如果为10万,需要耗费的内存将近40GB。
在实际应用中,我们想比较两个源代码文件(这里把行看作一个序列节点),几万行的文件也比较常见,用目前的这种耗费巨大内存算法不太现实(IBM的Java IDE开发环境Eclipse默认的比较文件的大小上限为1MB)。所以,必须要想办法来减少这个二维数组的内存。
实际上,如图2所示,该数组有好多地方存的数字都是一样的,后来有人改进了这个算法,数组里面的数字只有两种:0和1,1表示数字跟前面的不同,0表示跟前面的相同。这样,数组可以声明为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所示算法的核心思想是通过一个二维布尔数组arrCon[m,n]作为临时变量存储序列比较过程中的状态,然后通过循环遍历得出两个序列的公共子序列。
随着计算量的增加,LCS算法中布尔值的存取也出现了消耗内存大的问题。为进一步减少内存的占用,此种改进算法有必要进一步优化。
还能不能进一步减少这个二维布尔数组arrCon[m,n]的内存呢?表面上看,bool类型只占一个字节,不能再减少了。实际上,我们知道计算机是用0和1来存储数据的,一个字节(Byte)有8位(bit)。用一个字节也就是8个位来存储一个0或者1似乎有些浪费。如果语言能提供位(bit)这种数据类型就好了,用这种类型定义的数组,理论上这个数组所消耗的内存只有最初int数组的1/32。
以C/C++为例,C/C++本身没有提供位(bit)这种数据类型,不过我们可以定义结构体sbyte来访问位。如图4所示。用sizeof(sbyte)检查一下,运算结果确实是1。
假设我们原来要定义一个m行n列的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算法内存的占用。
我们知道,在主流的计算机语言里,都有位运算。下表是位运算的运算符及其含义:
利用位运算,我们可以将初始值为0数的任意一位设为1。以下都是假设int用四个字节(32位)存储。
给一个数A,初始值为0,如下:
00000000 00000000 00000000 00000000
如果想将A从右边起的第七位设为1,可以给定一个数B,这个数除开右起第七位为1外,其它各位都是0,如下:
00000000 00000000 00000000 01000000
执行A=A|B,即可将A的第七位设为1,“|”表示两个位不同则为1,否则为0。运算结果如下:
00000000 00000000 00000000 01000000
同样,执行A=A|(0x01<<5),即可将A的第六位设为1。0x01存储形式为:
00000000 00000000 00000000 00000001
0x01<<5的运算结果如下:
00000000 00000000 00000000 00100000
执行A=A|(0x01<<5)后,结果如下:
0000000 00000000 000000000 00100000
综上,如果想让初始值为0的数A的第N位设为1,进行以下运算即可:
A=A|(0x01<<(N-1))
可见,利用位运算,可以将1存储到一个数的任一个位上。
利用位运算,我们还可以判断一个数的某一位是不是1。
假如,我们想判断一个数从右边起的第7位是不是1,可以给定一个判定数,这个数除开右边起第7位为1外,其他所有位均为0,如下所示:
某 数(A):00000000 10010100 10101000 0?001100
判定数(B):00000000 00000000 00000000 01000000
假设A&B=C(“&”代表按位与。如果两个位都是1,则为1,否则为0。),由于B除开右边起第七位外,其他所有位都是0,所以经过按位与运算后的数C除开右边起第七位外,其他位也是0,由于B的右边起第七位是1,所以如果A的第七位为0,则C的第七位也是0,如果A的第七位是1,则C的第七位也是1。也就是如果A的第七位是1的话,则B等于C,如果A的第七位是0的话,则C等于0。
综上,如果要判断A的第N位是否为1,只要需要进行以下判断:判断A&(0x01<<(N-1))后,其结果是否为0即可。结果为0代表要判断A的第N位为0,否则要判断A的第N位为1。
由图3.a、3.b可以看到,布尔值的存储是LCS算法的一个关键步骤。图5为传统做法、C/C++位直接存储以及本发明的位运算存储就布尔值存储流程进行了对比。从中看到,利用本发明的位运算存储可以达到LCS算法的布尔值存储要求。
由图3.a、3.b可以看到,布尔值的读取是LCS算法的另一关键步骤。图6为传统做法、C/C++位直接读取以及本发明的位运算读取就布尔值读取流程进行了对比。从中看到,利用本发明的位运算读取可以达到LCS算法的布尔值读取要求。
如果要存储m*n个布尔值,传统做法是用一个二维m*n的布尔数组,利用前述C/C++的sbyte结构体,由于可以直接访问位(bit),所以可以用一个一维的m*n/8列的sbyte数组存储m*n个布尔值,如果再利用本发明所述的位运算存储及位运算读取,可以用一个一维的m*n/32的整形(int)数组存储m*n个布尔值。m、n均为大于等于1的正整数。
本发明公开了一种节省内存的LCS算法,本发明以图3.a、3.b所示的LCS算法为基础,对用于存储比较状态的二维布尔数组进行优化,采用一维整形数组存储比较状态,并用位运算存储及位运算读取实现对该一维整形数组的存储、读取,其余运算过程及步骤均未修改。即:
本发明所述节省内存的LCS算法,用一个一维整形数组存储两个序列在比较过程中的比较状态数据;第一个序列长度为m,第二个序列长度为n,所述比较状态数据为布尔值,比较状态数据共m*n个,存储比较状态数据的一维整形数组为一个一维的m*n/32的整形数组;在向该一维整形数组内存储比较状态数据时,用位运算存储实现对该一维整形数组的存储,每一位(bit)存储一个比较状态数据;在从该一维整形数组内读取比较状态数据时,用位运算读取实现对该一维整形数组的读取。更具体地说:
本发明所述节省内存的LCS算法,当需要存储比较状态数据时,包括以下步骤,参见图5:
步骤1,计算整形int所占位数;
例如:int iSize=sizeOf(int)*8;int为整型数据类型,sizeOf是C/C#语言中判断数据类型长度符,简单的说其作用就是返回一个对象或者类型所占的内存字节数,一个字节(Byte)有8个位(bit),所以要乘以8,一个位表示0或1;不同语言方法可能不同,本发明不再逐一举例说明;
步骤2,声明一个一维整形数组arMatrix;
例如:int[]arMatrix=new int[m*n/iSize+1];m、n分别为需要比较的两个字符串的长度,第一个字符串长度为m,第二个字符串长度为n,“+1”是为了确保数组够用,因为进行iSize取整的是时候可能会隐含减少一列数据;
本发明所述的LCS算法要存储m*n个布尔值,理论上要求使用m*n长度的一维布尔数组(或m*n的二维布尔数组),这里为什么要除以iSize呢?是因为一个int值是由iSize个位组成的,也就是说一个int值可以表示iSize个0和1;对该数组要用本发明所述的位运算存储及位运算读取算法来存储和读取;
步骤3,确定第i行j列元素在一维数组的第几列;
例如:int index=(i*n+j)/iSize;i和j来自LCS算法运算过程,请参见图3.a,3.b;i*n+j表示第i行j列元素的顺序号,数组中一个数据可以存储iSize个值,对顺序号取整即得到列号;
步骤4,确定第i行j列元素在第index列数据的第几位;
例如:int offset=(i*n+j)%iSize;对顺序号取余算出位偏移,即其在数据中的第几位;
步骤5,生成一个第offset位数据为true的数offsetData;
例如:int offsetData=(int)0x01<<offset;给一个数据0x01,其右起第一位为1,其他所有位都为0,通过向左偏移offset位后得到一个右起第offset位为1,其他所有位为0的数;
步骤6,将true值存储到第index列数据:arMatrix[index]|=offsetData。
上述位运算存储只存储true值(值为1),数组在初始化的时候,每个位存储的都是0,所以没有必要再去通过运算把某一位变成0,LCS算法过程会触发存储比较状态数据,请参见图3.a,3.b。图3.a主要讲的是读取状态数据,图3.b主要讲的是存储状态数据
本发明所述节省内存的LCS算法,当需要读取比较状态数据时,包括以下步骤,参见图6:
步骤1,声明布尔变量bVal;例如:bool bVal;
步骤2,确定第i行j列元素在一维数组的第几列;
例如:int index=(i*n+j)/iSize;i和j来自LCS算法运算过程,i*n+j表示第i行j列元素的顺序号,数组中一个数据可以存储iSize个值,对顺序号取整即得到列号;
步骤3,确定第i行j列元素在第index列数据的第几位;
例如:int offset=(i*n+j)%iSize;对顺序号取余算出位偏移,及其在数据中的第几位;
步骤4,生成一个第offset位数据为true的数offsetData;
例如:int offsetData=(int)0x01<<offset;给一个数据0x01,其右起第一位为1,其他所有位都为0,通过向左偏移offset位后得到一个右起第offset位为1,其他所有位为0的数;
步骤5,进行与运算并返回运算结果:结果为0代表一维数组第offset位数据为0,否则代表一维数组第offset位数据为1。
例如:bVal=(arMatrix[index]&offsetData!=0)。由于offsetData除右起第offset位为1外,其他都为0,进行与运算,如果第index列数据右起第offset为0,返回结果肯定为0;如果返回结果不为0,即表示true(为1)。即:第index列数据arMatrix[index]与第offset位数据为true的数offsetData进行&运算,返回运算结果:结果为0代表一维数组第offset位数据为0,否则代表一维数组第offset位数据为1。
下表是传统存取、C/C++位直接存取和位运算直接存取从内存占用、复杂性等各个方面的比较。
参数 | 传统存取 | C/C++位直接存取 | 位运算存取 |
内存 | 1 | 1/8 | 1/8 |
逻辑复杂性 | 无 | 复杂 | 较复杂 |
代码流程 | 无 | 多 | 少 |
代码行 | 少 | 多 | 中 |
适用语言 | 所有 | C/C++ | 所有 |
由上表可见,传统存取虽然简单,但消耗内存是其他两种方法的8倍,所以这里不予考虑。相比C/C++位直接存取,位运算存取方式除了代码行要少很多,不需要进行很多的if/else/switch判断,不需要定义新的数据类型,更为重要的是,这种算法可以广泛移植到其他语言。结合到LCS算法,原来2万行文件比较,需要约1600MB内存,现在只需要50MB,原来10万行文件比较需要40GB内存,现在只需要1.25GB。
以下为通过位运算存取布尔值算法源码(C#)
Claims (3)
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。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN 201110101299 CN102184165B (zh) | 2011-04-22 | 2011-04-22 | 一种节省内存的lcs算法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN 201110101299 CN102184165B (zh) | 2011-04-22 | 2011-04-22 | 一种节省内存的lcs算法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN102184165A true CN102184165A (zh) | 2011-09-14 |
CN102184165B CN102184165B (zh) | 2013-01-02 |
Family
ID=44570342
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN 201110101299 Active CN102184165B (zh) | 2011-04-22 | 2011-04-22 | 一种节省内存的lcs算法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN102184165B (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111125313A (zh) * | 2019-12-24 | 2020-05-08 | 武汉轻工大学 | 文本相同内容查询方法、装置、设备及存储介质 |
CN113032291A (zh) * | 2021-03-31 | 2021-06-25 | 四川长虹空调有限公司 | 优化数据内存分配的方法、及查找数据与改写数据的方法 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101484895A (zh) * | 2006-07-07 | 2009-07-15 | 新叶股份有限公司 | 比特序列检索装置、检索方法以及程序 |
EP2098965A1 (en) * | 2006-11-28 | 2009-09-09 | S. Grants Co., Ltd. | Splitting/connecting method for coupled node tree, and program |
-
2011
- 2011-04-22 CN CN 201110101299 patent/CN102184165B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101484895A (zh) * | 2006-07-07 | 2009-07-15 | 新叶股份有限公司 | 比特序列检索装置、检索方法以及程序 |
EP2098965A1 (en) * | 2006-11-28 | 2009-09-09 | S. Grants Co., Ltd. | Splitting/connecting method for coupled node tree, and program |
Non-Patent Citations (2)
Title |
---|
《Seventh International Symposium on String Processing and Information Retrieval, 2000》 20001231 Bergroth, L. etc. A survey of longest common subsequence algorithms 第39-48页 1-3 , * |
《武夷学院学报》 20100430 郑翠玲 最长公共子序列算法的分析与实现 正文第44-48页 1-3 第29卷, 第2期 * |
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111125313A (zh) * | 2019-12-24 | 2020-05-08 | 武汉轻工大学 | 文本相同内容查询方法、装置、设备及存储介质 |
CN111125313B (zh) * | 2019-12-24 | 2023-12-01 | 武汉轻工大学 | 文本相同内容查询方法、装置、设备及存储介质 |
CN113032291A (zh) * | 2021-03-31 | 2021-06-25 | 四川长虹空调有限公司 | 优化数据内存分配的方法、及查找数据与改写数据的方法 |
Also Published As
Publication number | Publication date |
---|---|
CN102184165B (zh) | 2013-01-02 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US11899667B2 (en) | Efficient use of trie data structure in databases | |
CN104360865B (zh) | 一种序列化方法、反序列化方法及相关设备 | |
Kaplan et al. | PRINS: Processing-in-storage acceleration of machine learning | |
CN105706092A (zh) | 四值模拟的方法和系统 | |
WO2015010509A1 (zh) | 一种基于一维线性空间实现Trie树的词典检索方法 | |
CN100476824C (zh) | 存储元素的方法与系统及查找元素的方法与系统 | |
Mittal | A survey on applications and architectural-optimizations of micron’s automata processor | |
Katsura et al. | Position heaps for parameterized strings | |
CN106681981A (zh) | 中文词性的标注方法和装置 | |
CN102184165B (zh) | 一种节省内存的lcs算法 | |
Chen et al. | Efficient graph similarity search in external memory | |
Anthes | Happy birthday, RDBMS! | |
Hayfron-Acquah et al. | Improved selection sort algorithm | |
Eger | Sequence alignment with arbitrary steps and further generalizations, with applications to alignments in linguistics | |
Wong et al. | Mining favorable facets | |
CN103761270B (zh) | 一种串数据词典的有序构造及检索方法 | |
Zhang et al. | Efficient indexing of binary LSH for high dimensional nearest neighbor | |
Burdzy et al. | Twin peaks | |
Stojmenovic | Listing combinatorial objects in parallel | |
CN103019801B (zh) | 一种应用于高速数字io波形引擎的编译器 | |
Choudum et al. | Embedding height balanced trees and Fibonacci trees in hypercubes | |
Wang et al. | An Optimal Algorithm for Prufer Codes. | |
Jarollahi et al. | Algorithm and architecture for a multiple-field context-driven search engine using fully-parallel clustered associative memories | |
Moghaddam et al. | Large-scale data sorting using independent equal-length subarrays | |
Zhou et al. | Cuckoo linear algebra |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
TR01 | Transfer of patent right | ||
TR01 | Transfer of patent right |
Effective date of registration: 20200818 Address after: 430000 part of the third floor of cable building, Guandong science and Technology Park, Donghu New Technology Development Zone, Wuhan, Hubei Province Patentee after: Wuhan Changjiang Computing Technology Co., Ltd Address before: China Science and Technology Park Dongxin road East Lake Development Zone 430074 Hubei Province, Wuhan City, No. 5 Patentee before: FIBERHOME TELECOMMUNICATION TECHNOLOGIES Co.,Ltd. |