C语言求解最长公共子字符串问题及相关的算法分析

C语言求解最长公共子字符串问题及相关的算法分析

简介

在文本处理中,求解最长公共子字符串问题是一个普遍的、重要的问题。该问题描述如下:给定两个字符串s1和s2,求它们的最长公共子字符串,即在两个字符串中都出现过的最长的子串。

算法分析

在求解最长公共子字符串问题中,有多种不同的算法,这里介绍两种常用的算法:暴力枚举和动态规划。

暴力枚举算法

暴力枚举算法是最朴素、最简单的算法,也是一种较慢的算法。该算法基本思路是:枚举s1的所有子串和s2的所有子串,判断它们是否相等,记录最长的相等子串即可。

暴力枚举算法的时间复杂度为O(n^3),但它实现简单易懂,可以作为其他算法的比较标准。下面给出暴力算法的C语言实现代码:

#include <stdio.h>
#include <string.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int getLCS(char* s1, char* s2, int len1, int len2)
{
    int maxLCS = 0;
    int len;
    for (int i = 0; i < len1; i++)
    {
        for (int j = 0; j < len2; j++)
        {
            len = 0;
            while (i + len < len1 && j + len < len2 && s1[i+len] == s2[j+len])
            {
                len++;
            }
            maxLCS = max(maxLCS, len);
        }
    }
    return maxLCS;
}

int main()
{
    char s1[] = "abcde";
    char s2[] = "bdewfabc";
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int res = getLCS(s1, s2, len1, len2);
    printf("The length of the LCS is %d\n", res);
    return 0;
}

动态规划算法

动态规划算法是一种常用的、高效的算法,它的基本思路是将原问题分解成多个子问题,通过保存中间结果,避免重复计算,实现高效求解。该算法在求解最长公共子字符串问题时,需要构建一个二维的DP矩阵,通过矩阵的更新计算出最长公共子串的长度。

动态规划算法的时间复杂度为O(n^2),要比暴力算法的时间复杂度低得多,下面给出动态规划算法的C语言实现代码:

#include <stdio.h>
#include <string.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int getLCS(char* s1, char* s2, int len1, int len2)
{
    int maxLCS = 0;
    int dp[len1+1][len2+1];
    for (int i = 0; i <= len1; i++)
    {
        dp[i][0] = 0;
    }
    for (int j = 0; j <= len2; j++)
    {
        dp[0][j] = 0;
    }
    for (int i = 1; i <= len1; i++)
    {
        for (int j = 1; j <= len2; j++)
        {
            if (s1[i-1] == s2[j-1])
            {
                dp[i][j] = dp[i-1][j-1] + 1;
                maxLCS = max(maxLCS, dp[i][j]);
            }
            else
            {
                dp[i][j] = 0;
            }
        }
    }
    return maxLCS;
}

int main()
{
    char s1[] = "abcde";
    char s2[] = "bdewfabc";
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int res = getLCS(s1, s2, len1, len2);
    printf("The length of the LCS is %d\n", res);
    return 0;
}

上述代码中使用了一个二维的DP矩阵,通过分别比较s1的第i个字符和s2的第j个字符,判断是否相等,来更新矩阵中dp[i][j]的值。最终DP矩阵中的最大值即为最长公共子串的长度。

示例说明

下面给出两个示例说明,分别使用暴力枚举算法和动态规划算法,求解两个字符串的最长公共子串长度。

示例1:使用暴力枚举算法求解

s1 = "ABCBAB", s2 = "BABCBABC"

#include <stdio.h>
#include <string.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int getLCS(char* s1, char* s2, int len1, int len2)
{
    int maxLCS = 0;
    int len;
    for (int i = 0; i < len1; i++)
    {
        for (int j = 0; j < len2; j++)
        {
            len = 0;
            while (i + len < len1 && j + len < len2 && s1[i+len] == s2[j+len])
            {
                len++;
            }
            maxLCS = max(maxLCS, len);
        }
    }
    return maxLCS;
}

int main()
{
    char s1[] = "ABCBAB";
    char s2[] = "BABCBABC";
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int res = getLCS(s1, s2, len1, len2);
    printf("The length of the LCS is %d\n", res);
    return 0;
}

输出结果为:The length of the LCS is 3

示例2:使用动态规划算法求解

s1 = "ABCBAB", s2 = "BABCBABC"

#include <stdio.h>
#include <string.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int getLCS(char* s1, char* s2, int len1, int len2)
{
    int maxLCS = 0;
    int dp[len1+1][len2+1];
    for (int i = 0; i <= len1; i++)
    {
        dp[i][0] = 0;
    }
    for (int j = 0; j <= len2; j++)
    {
        dp[0][j] = 0;
    }
    for (int i = 1; i <= len1; i++)
    {
        for (int j = 1; j <= len2; j++)
        {
            if (s1[i-1] == s2[j-1])
            {
                dp[i][j] = dp[i-1][j-1] + 1;
                maxLCS = max(maxLCS, dp[i][j]);
            }
            else
            {
                dp[i][j] = 0;
            }
        }
    }
    return maxLCS;
}

int main()
{
    char s1[] = "ABCBAB";
    char s2[] = "BABCBABC";
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int res = getLCS(s1, s2, len1, len2);
    printf("The length of the LCS is %d\n", res);
    return 0;
}

输出结果为:The length of the LCS is 3

以上两个示例分别展示了使用暴力枚举算法和动态规划算法求解最长公共子字符串问题的基本思路和操作过程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言求解最长公共子字符串问题及相关的算法分析 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 一问学会QT时间类

    如何学习QT时间类 一、了解QT时间类 QT时间类是QT框架提供的一个用于处理时间的类,它提供了很多便捷的方法来进行时间计算和转换,并且支持不同的时间格式。其中最常用的时间类有QDateTime、QTime和QDate。 二、基本使用方法 2.1 获取当前时间 使用QDateTime::currentDateTime()函数可以获取当前的时间。 QDateT…

    C 2023年5月23日
    00
  • C++两个cpp文件间如何进行各自函数的调用方式

    当我们在一个项目中有多个 C++ 源文件时,我们需要知道如何在不同的文件中调用其它文件的函数。 下面是两个cpp文件间如何进行各自函数的调用方式的攻略: 声明和定义 要在一个文件中使用另一个文件中定义的函数,我们必须将该函数的定义标记为 “extern”,并在需要使用它的文件中进行声明。 例如,如果我们有两个文件,一个叫做 main.cpp 和另一个叫做 h…

    C 2023年5月23日
    00
  • C++性能剖析教程之循环展开

    下面是关于“C++性能剖析教程之循环展开”的完整攻略: 1. 什么是循环展开 循环展开是一种优化技术,指将循环体语句复制若干次以减少分支和循环的开销,从而提高代码的执行速度。循环展开时需要注意的是展开的次数(即展开因子)应该适量,过大会导致代码膨胀、缓存未命中率增加等问题,影响性能。 循环展开通常需要配合编译命令中的优化选项一起使用,以便在编译时对代码进行优…

    C 2023年5月23日
    00
  • C++中4种类型转换的方法分享

    当我们在C++编程中需要将一个数据类型转换为另一个数据类型时,可以使用以下四种类型转换方法: 1. 隐式类型转换 隐式类型转换(implicit conversion)是由编译器自动完成的类型转换,不需要程序员显式地调用转换函数或者使用强制类型转换运算符。例如,将整型变量赋给浮点型变量时,编译器会自动将整型变量转换为浮点型变量。示例代码如下: int i =…

    C 2023年5月30日
    00
  • C语言所有经典排序方法的实现代码

    C语言所有经典排序方法的实现代码 本文将会讲解C语言中所有经典的排序算法,包括冒泡排序、选择排序、插入排序、快速排序、归并排序以及堆排序,并提供完整的代码实现。 冒泡排序 冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。 void bubbleSort(int arr[], int n) { i…

    C 2023年5月24日
    00
  • 详析C++中的auto

    详析C++中的auto “auto”是C++11新添加的一个关键词,其作用是让编译器根据初始值推算变量的类型。下面详细介绍auto的使用方法和注意事项。 auto的使用方法 自动推导变量类型 使用auto关键词,可以让编译器根据初始值自动推算变量类型。例如: auto i = 10; auto b = true; auto s = "hello&q…

    C 2023年5月23日
    00
  • Visual Studio 2022 的安装和创建C++项目(图文教程)

    下面是详细讲解 Visual Studio 2022 的安装和创建 C++ 项目的攻略: 1.下载和安装 Visual Studio 2022 首先,我们需要下载并安装 Visual Studio 2022。可以在微软官网上下载安装包,具体流程如下: 1.1 访问 Visual Studio 官网 首先,在浏览器中访问 Visual Studio 官网。 1…

    C 2023年5月30日
    00
  • js中把JSON字符串转换成JSON对象最好的方法

    把JSON字符串转换成JSON对象是前端开发中非常常见的操作,也可以用于从后台获取数据后进行解析。下面是实现这个功能的完整攻略。 使用JSON.parse()方法 在JavaScript中,可以使用JSON.parse()方法将JSON字符串转换成JSON对象。该方法需要一个JSON格式的字符串参数,并返回一个JavaScript对象。 下面是一个示例,我们…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部