IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法分析:C语言实现动态规划之最长公共子序列 -> 正文阅读

[数据结构与算法]算法分析:C语言实现动态规划之最长公共子序列

最长公共子序列问题:

????????下面的简单问题说明了动态规划的基本原理。在字母表一∑上,分别给出两个长度为n和m的字符串A和B,确定在A和B中最长公共子序列的长度。这里,A = a?a?...an。的子序列是一个形式为a?ka?k...aik的字符串,其中每个i都在1和n之间,并且1<i?< i?<…<ik≤n。例如,如果∑= {x, y,z},A = zxyxyz和B= xyyzx,那么xzy 同时是A和B的长度为3的子序列。然而,它不是A和B最长的公共子序列,因为字符串xyyz也是A和B公共的子序列,由于这两个字符串没有比4更长的公共子序列,因此,A和B的最长的公共子序列的长度是4

????????解决这个问题的-一种途径是蛮力搜索的方法:列举A所有的2^n个子序列,对于每一个子序列在O( m)时间内来确定它是否也是B的子序列。很明显,此算法的时间复杂性是O时间复杂度(m22),是指数复杂性的。

????????为了使用动态规划技术,我们首先寻找--个求最长公共子序列长度的递推公式,令A = a?a?...an和B= b?b?...bm,令L[i,j]表示a?a?...ai和b?b?...bj的最长公共子序列的长度。

????????注意、i和j可能是0,此时,a?a?...ai和b?b?...bj中的一个或同时可能为空字符串。即如果i =0或 j =o,那么L[i,j]=0。很容易证明下面的观察结论。

????????如果i和j都大于0,那么

? ? ? ? 1.若ai=bj, L[i,j]= L[ i-1,j - 1]+1;

·? ? ? ? 2.若ai≠bj, L[i,j ]= max{L[i,j - 1],L[ i- 1,j] }。

最长公共子序列算法伪码:

?

?最长公共子序列公式:

?

?最长公共子序列解题思想:


A的长度为5 B的长度为7
A字符串:zxyyz
B字符串:zyxzyxz
    0   z   y   x   z   y   x   z
0   0   0   0   0   0   0   0   0
z   0   0   0   0   0   0   0   0
x   0   0   0   0   0   0   0   0
y   0   0   0   0   0   0   0   0
y   0   0   0   0   0   0   0   0
z   0   0   0   0   0   0   0   0
z与z相遇即相等,将左上角+1,并将其余的比较大小,1>0,所以将其他的值变为1,即得到下图↓
    0   z   y   x   z   y   x   z
0   0   0   0   0   0   0   0   0
z   0   1   1   1   1   1   1   1
x   0   1   1   1   1   1   1   1
y   0   1   1   1   1   1   1   1
y   0   1   1   1   1   1   1   1
z   0   1   1   1   1   1   1   1
x与x相遇即相等,y与y相遇即相等,将左上角+1得2,并将其余的比较大小,2>1,所以将其他的值变为2,即得到下图↓
    0   z   y   x   z   y   x   z
0   0   0   0   0   0   0   0   0
z   0   1   1   1   1   1   1   1
x   0   1   1   2   2   2   2   2
y   0   1   2   2   2   2   2   2
y   0   1   2   2   2   2   2   2
z   0   1   2   2   2   2   2   2
z与z相遇即相等,y与y相遇即相等,将左上角+1得3,并将其余的比较大小,3>2,所以将其他的值变为3,即得到下图↓
    0   z   y   x   z   y   x   z
0   0   0   0   0   0   0   0   0
z   0   1   1   1   1   1   1   1
x   0   1   1   2   2   2   2   2
y   0   1   2   2   2   3   3   3
y   0   1   2   2   2   3   3   3
z   0   1   2   2   3   3   3   3
z与z相遇即相等,将左上角+1得4,没剩余得值了,所以退出程序不用比较,即得到下图↓
    0   z   y   x   z   y   x   z
0   0   0   0   0   0   0   0   0
z   0   1   1   1   1   1   1   1
x   0   1   1   2   2   2   2   2
y   0   1   2   2   2   3   3   3
y   0   1   2   2   2   3   3   3
z   0   1   2   2   3   3   3   4

核心代码就那几行:

for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(a[i-1]==b[j-1])
                c[i][j]=c[i-1][j-1]+1;
            else
                c[i][j]=max(c[i][j-1],c[i-1][j]);
        }
    }

将数据一步一步的带入代码就可以理解了!

?代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
void lcs();
int max(int a,int b);

int main()
{
    lcs();
    return 0;
}
int max(int a,int b)
{
    return a>b?a:b;
}
void lcs()
{
    int n,m,i,j;
    char *a,*b;
    printf("分别输入A和B的长度:");
    scanf("%d%d",&n,&m);

    a=(char *)malloc(n*sizeof(char));
    b=(char *)malloc(n*sizeof(char));
    int c[n+1][m+1];

    printf("输入A字符串:");
        scanf("%s",a);
    getchar();
    printf("输入B字符串:");
        scanf("%s",b);
    for(i=0;i<=n;i++)c[i][0]=0;
    for(j=0;j<=m;j++)c[0][j]=0;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(a[i-1]==b[j-1])
                c[i][j]=c[i-1][j-1]+1;
            else
                c[i][j]=max(c[i][j-1],c[i-1][j]);
        }
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            printf("%d  ",c[i][j]);
        }
        printf("\n");
    }
    printf("\n%d\n",c[n][m]);
    printf("按任意键继续\n");
}

结果实现:?

?

希望这对你有帮助!?

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 13:04:40  更:2021-10-27 13:05:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:31:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码