zoukankan      html  css  js  c++  java
  • 最长公共子序列

    同样,注意和最长公共子字符串的区别,子序列没有字符连续的要求。问题描述如下:

    给定两个字符串str1和str2,求二者的最长公共子序列,一个具体的实例说明是若str1 = “13546”,str2 =“2153467”,那么他们的最长公共子序列为“1346”。

    这是算法导论上用来介绍动态规划的时候一个很经典的问题,怎么看有没有最优子结构呢?构建一张表count,count[i][j]表示str1[0,…,i]和str2[0,…,j]的最长子序列,分析如下:

    假定现在需求str1[0,…,i]和str2[0,…,j]的最长子序列,那么有以下几种情况:

    1.str1[i] ==str2[j] : 此时count[i][j] =count[i-1][j-1]

    2.str1[i] != str2[j] : 此时 count[i][j] =max(count[i-1][j],count[i][j-1]

    一个例子如下:

    image

    上图中 e表示边界,m表示 往做左上角转,l表示left,u表示up。

    与之相对应的代码如下:

    int lcs_sequence(char *str1,char *str2,int str1_len,int str2_len)
    {
            
        //动态规划表
        char *count  = (char *)malloc(str2_len*str1_len*sizeof(char));
        char *record = (char *)malloc(str2_len*str1_len*sizeof(char));
     
        //分别记录当前最长的子序列长度 和 轨迹
     
        for(int h =0;h<str1_len;h++)
        {
            for(int w=0;w<str2_len;w++)
            {
                if(str1[h]==str2[w])
                {
                
                    if(h==0 || w==0)
                    {
                        count[h*str2_len+w] = 1;
                        record[h*str2_len+w] = 'm';    
                    }
                    else
                    {
                        count[h*str2_len+w] = count[(h-1)*str2_len+w-1]+1;
                        record[h*str2_len+w] = 'm';        
                    }
                    
                }
                else
                {
                    if(h == 0 || w ==0)
                    {
                        count[h*str2_len+w] = 0;
                        record[h*str2_len+w] = 'e';    
                    }
                    else
                    {
                        if(count[(h-1)*str2_len+w]>count[h*str2_len+w-1])
                        {
                            count[h*str2_len+w] = count[(h-1)*str2_len+w];
                            record[h*str2_len+w] = 'u';
                        }
                        else
                        {
                            count[h*str2_len+w] = count[h*str2_len+w-1];
                            record[h*str2_len+w] = 'l';
                        }
     
                    }
                }
            }
        }
     
    //按照轨迹输出
     
        int maxSubSeqLen = count[str1_len*str2_len-1];
        char * result = (char *)malloc((maxSubSeqLen+1)*sizeof(char));
        result[maxSubSeqLen] = '';
        int cur = maxSubSeqLen-1;
        int i= str1_len-1;int j =str2_len-1;
     
        while(true)
        {
            if(i<0||j<0)break;
            if(record[i*str2_len+j] == 'm') 
            {
                printf("%c
    ",str2[j] );
                result[cur] = str2[j];
                i--;j--;cur--;
            }
            if(record[i*str2_len+j] == 'e')break; 
            if(record[i*str2_len+j] == 'l')
            {
                j--;
            }
            if(record[i*str2_len+j] == 'u')
            {
                i--;
            } 
     
        }
     
     
        printf("
    the longest common subseq is : %s (length = %d)",result,maxSubSeqLen);
     
        return maxSubSeqLen;
     
    }
  • 相关阅读:
    算法31----单调数列
    算法30----三维形体的表面积、周长
    2、Attentive Group Recommendation----注意力集中的群组推荐
    1、Attention_based Group recommendation——基于注意力机制的群组推荐
    算法29-----最大三角形面积和周长
    算法28-----范围求和
    BPR贝叶斯个性化排序算法
    Testing
    Git
    Testing
  • 原文地址:https://www.cnblogs.com/obama/p/3224120.html
Copyright © 2011-2022 走看看