《算法导论》-最大公共子串(连续) C语言版

来源:互联网 发布:r语言按列读取csv数据 编辑:程序博客网 时间:2024/06/05 04:22

1、最大公共子串与最大公共子序列

最大公共子串是指两个序列连续的最大公共子序列,例如 "efghi"和"eghib"的最大公共子串就是“ghi"


采用DP的思想,如果str1[i] = str2[j],那么此处的包含str1[i] 和 str2[j]公共子串的长度必然是包含str1[i-1]和str2[j-1]的公共子串的长度加1,那么现在我们可以重新定义lcs(i,j),即是lcs(i,j) = lcs(i-1,j-1) + 1,反之,lcs(i,j) = 0。

2.算法的改进
由于每一行的数据的生成只需要通过两个母串的对比,以及借助上一行的结果得到,因此除了当前行的上一行,之前行的数据均可以被抛弃。因此,该算法只需要用于保存上一行的计算结果的长为LEN的辅助数组空间。改进后的算法空间复杂度为O(min(m,n))
3、代码实现(C语言版)


#include <stdio.h>#include <stdlib.h>#include <string.h>/**************************************************************函数:void Find_conLCS( char *str1, char *str2)str1:待比较字符串1str2:待比较字符串2返回值:无打印值:输出最大公共序列长度以及最大公共序列时间复杂度:O(mn)空间复杂度:O(mn)***************************************************************/void Find_conLCS( char *str1, char *str2){int i,j;int len = 0, end = -1, start = 0;int len1 = strlen(str1),len2 = strlen(str2);int **c = (int **)malloc(sizeof(int *) * (len1 + 1));for( i = 0; i <= len1; i++ )c[i] = (int *)malloc(sizeof(int) * (len2 + 1));for( i = 0; i <= len1; i++ )//这里必须要把动态申请的二位数组清零,否则会有bugfor( j = 0; j <= len2; j++ )c[i][j] = 0;for( i = 1; i <= len1; i++ )for( j = 1; j <= len2; j++ ){if( str1[i-1] == str2[j-1])c[i][j] = c[i-1][j-1] + 1;if( c[i][j] > len){len = c[i][j];end = j;}}start = end - len + 1;printf("The number of Longest of continuous subsequence is : %d\n", len);printf("The longest of continuous subsequence is :");for( j = start; j <= end; j++)printf("%c ", str2[j-1]);printf("\n");for( i = 0; i <= len1; i++ )free(c[i]);free(c);}/**************************************************************函数:void Find_conLCS1( char *longstr, char *shortstr)str1:待比较字符串1str2:待比较字符串2返回值:无打印值:输出最大公共序列长度以及最大公共序列时间复杂度:O(mn)空间复杂度:O(len(shortstr))***************************************************************/void Find_conLCS1( char *longstr, char *shortstr){int i, j;int len1 = strlen(longstr),len2 = strlen(shortstr);int len = 0, end = -1, start;int *c = (int *)malloc(sizeof(int) * (len2 + 1));for( i = 0; i <= len2; i++ )c[i] = 0;for( i = 0; i <= len1; i++)for( j = len2-1; j >= 0; j--){if( longstr[i] == shortstr[j]){if( i == 0 || j == 0 )c[j] = 1;else c[j] = c[j-1] +1;}else c[j] = 0;if( c[j] > len){len = c[j];end = j;}}start = end - len + 1;printf("The number of Longest of continuous subsequence is : %d\n", len);printf("The longest of continuous subsequence is :");for( i = start; i <= end; i++ )printf("%c ", shortstr[i]);printf("\n");free(c);}int main(){char x[10] = "abcdefghi";char y[10] = "bdeghibjk";Find_conLCS1(x,y);system("pause");}
0 0
原创粉丝点击