求两个字符串最大子串的lcs算法

/*************************************************************************
    > File Name:                lcs.c
    > Author:                   dingzhengsheng
    > Mail:                             [email protected]
    > Created Time:             2015年05月20日 星期三 16时07分50秒
    > Version:                  v0.01
    > Description:
    > History:
 ************************************************************************/

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include <unistd.h>
#include<string.h>
#include<sys/time.h>
#include<ctype.h>
#include"test_time.h"

#define DEBUG   1

void slow_bb(char *a,int lena,char *b,int lenb, char *c)
{
        int i;
        int j;
        int index;
        int max=0;
        int num=0;
        int start;

        for(i=0; i<lena; i++)
        {
                for(j=0; j<lenb; j++)
                {
                        int start1 = i;
                        int start2 = j;

                        while((start1 < lena-1) && (start2<lenb-1) && (a[start1++] == b[start2++]))
                                num++;

                        if(num > max)
                        {
                                max = num;
                                start = i;
                        }
                        num = 0;
                }
        }

        strncpy(c, a+start, max);

}

void lcs(char *a, int lena, char *b, int lenb, char *c)
{
        int i;
        int j;
        int s[lena+1];
        memset(s, 0, sizeof(int)*(lena+1));
        int maxlen = 0;
        int pos;

#ifdef DEBUG
        int *dbg;
        dbg= (int *)malloc(sizeof(int)*(lenb+1)*(lena+1));
        memset(dbg, 0, sizeof(int)*(lenb+1)*(lena+1));
#endif

        for(j=lenb-1; j>=0; j--)
        {
                for(i=0; i<lena; i++)
                {
                        if(b[j] == a[i])
                        {
#ifdef DEBUG
                                *(dbg+j*(lena+1)+i) = s[i] = s[i+1]+1;
#else
                                s[i] = s[i+1]+1;
#endif
                                if(s[i] > maxlen)
                                {
                                        maxlen = s[i] ;
                                        pos = i;
                                }
                        }
                        else
                        {
                                /*
                                if(s[i+1] > maxlen)
                                {
                                        maxlen = s[i+1];
                                        pos = i+1;
                                }
                                */
                                s[i] =  0;
                        }
                }
        }

#ifdef DEBUG
        for(i=0; i<lenb+1; i++)
        {
                if(i == 0)
                {
                        printf("  ");
                        for(j=0; j<lena; j++)
                                printf("%c ", a[j]);

                        printf("\n");
                }
                if(i == lenb)
                        printf(" ");
                for(j=0; j<lena+1; j++)
                {
                        if(j == 0)
                                printf("%c ", b[i]);
                        printf("%d ", *(dbg+i*(lena+1)+j));
                }
                printf("\n");
        }
#endif

        strncpy(c,&a[pos], maxlen);

}

void main(int argc, char *argv[])
{
        char *a;
        char *b;
        int a_len;
        int b_len;
        char *c;
        int n = 100;
        int i=0;

        if(argc >= 1)
                n = atoi(argv[1]);
        if(argc >= 3)
        {
                a_len = atoi(argv[2]);
                b_len = atoi(argv[3]);
        }

        a = malloc(a_len);
        b = malloc(b_len);
        c = malloc(a_len);

        for(i=0; i<a_len; i++)
                a[i] =random()%4 + 0x30;

        for(i=0; i<b_len; i++)
                b[i] =random()%4 + 0x30;

        printf("a=%s\n", a);
        printf("b=%s\n", b);
        memset(c, 0, sizeof(c));
        starts();
        for(i=0;i<n;i++)
                slow_bb(a, a_len, b, b_len, c);
        ends();
        printf("slow_bb c=%s ts=%lld\n", c, tt());

        memset(c, 0, sizeof(c));
        starts();
        for(i=0;i<n;i++)
                lcs(a, a_len, b, b_len, c);
        ends();
        printf("slow_bb c=%s ts=%lld\n", c, tt());

        free(a);
        free(b);
        free(c);

}

 test_time.c:

#include<stdio.h>
#include<time.h>
#include <unistd.h>
#include<string.h>
#include<sys/time.h>
#include<sys/resource.h>

#include"test_time.h"

#define SECTOUSEC 1000000

static struct timeval tv1,tv2;

void starts()
{
        gettimeofday(&tv1,NULL);
}

void ends()
{
        gettimeofday(&tv2,NULL);
}

long int get_diff_time(struct timeval *tv1, struct timeval *tv2)
{

           long int n;

              n = (tv2->tv_sec - tv1->tv_sec)*SECTOUSEC + tv2->tv_usec - tv1->tv_usec;
                     return n;
}

long int tt()
{
        return get_diff_time(&tv1, &tv2);
}

  test_time.h:

/*************************************************************************
    > File Name:                test_time.h
    > Author:                   dingzhengsheng
    > Mail:                             [email protected]
    > Created Time:             2015年05月20日 星期三 20时02分00秒
    > Version:                  v0.01
    > Description:
    > History:
 ************************************************************************/

#ifndef __TEST_TIME_H
#define __TEST_TIME_H

void starts();
void ends();
long int tt();

#endif

  

运行结果:(矩阵的打印受宏DEBUG控制),后者耗时更长就是因为打印矩阵

注:代码中没有对最长子串有多个的情况做处理,两个函数的结果可能会不一样,可以用数组记录多个相同长度最长子串

时间: 2024-10-10 08:18:31

求两个字符串最大子串的lcs算法的相关文章

求两个字符串最长公共子串

一.问题描述: 最长公共子串 (LCS-Longest Common Substring) LCS问题就是求两个字符串最长公共子串的问题.比如输入两个字符串"ilovechina"和“chinabest”的最长公共字符串有"china",它们的长度是5. 二.解法 解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0.然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.如下图: i   l   o  v  e  

java实现字符串匹配问题之求两个字符串的最大公共子串

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 近期在项目工作中有一个关于文本对照的需求,经过这段时间的学习,总结了这篇博客内容:求两个字符串的最大公共子串. 算法思想:基于图计算两字符串的公共子串.详细算法思想參照下图: 输入字符串S1:achmacmh    输入字符串S2:macham 1)第a步,是将字符串s1,s2分别按字节拆分,构成一个二维数组: 2)二维数组中的值如b所看到的,比方第一行第一列的值

java语言编程,求两个字符串的最大子串

package stringTest; public class StringDemo4 { public static void main(String[] args) { String str1 = "Ilikejavaverymuch"; String str2 = "java is useful"; StringDemo4 sd4 = new StringDemo4(); sd4.sop(sd4.getMaxSubString1(str1, str2));

求两个字符串的最长公共子串——Java实现

要求:求两个字符串的最长公共子串,如"abcdefg"和"adefgwgeweg"的最长公共子串为"defg"(子串必须是连续的) public class Main03{ // 求解两个字符号的最长公共子串 public static String maxSubstring(String strOne, String strTwo){ // 参数检查 if(strOne==null || strTwo == null){ return null

O(n) 求最长回文子串的 Manacher 算法

Manacher是一个可以在O(n)的时间内求出一个长度为n的字符串的算法. 以为回文子串有偶数长度,也有奇数长度,分别处理会很不方便. 所以在每两个字符中间插入一个无关字符,如‘#’,这样所有的回文子串都变为奇数长度. 两端在添加不同的无关字符防止匹配时越界. 如: abba 变成 $#a#b#b#a#& 预处理代码: void Prepare() { l = strlen(Str); S[0] = '$'; for (int i = 0; i <= l - 1; i++) { S[(i

关于两个字符串的kmp比对算法

关于两个字符串的kmp比对算法 假设有字符串X和Y,满足len(X)>len(Y),要比对这两个字符串. 我们知道,最朴实的方法,就是现将二者对齐,然后依次比对对应位置的字符.如果能匹配到Y最后位置,则匹配成功:如果匹配失败,则将Y右移一位,再从头进行匹配. 设字符串X为dababeabafdababcg:字符串Y为ababc. 这种比对方法如下所示: 起始时,二者对其,第一个字符不匹配 :| :dababeabafdababcg :ababc 右移一位,比对位置移动到Y起始位置 : | :da

[URAL-1517][求两个字符串的最长公共子串]

Freedom of Choice URAL - 1517 Background Before Albanian people could bear with the freedom of speech (this story is fully described in the problem "Freedom of speech"), another freedom - the freedom of choice - came down on them. In the near fu

求两个字符串最长公共子串(动态规划)

code如下: //Longest common sequence, dynamic programming method void FindLCS(char *str1, char *str2) { if(str1 == NULL || str2 == NULL) return; int length1 = strlen(str1)+1; int length2 = strlen(str2)+1; int **csLength,**direction;//two arrays to recor

EditDistance,求两个字符串最小编辑距离,动态规划

问题描述: 题目描述Edit DistanceGiven two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)You have the following 3 operations permitted on a word:     a) Insert a character