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日

相关文章

  • 谈谈RxJava2中的异常及处理方法

    针对“谈谈RxJava2中的异常及处理方法”的问题,我可以提供以下完整攻略。 异常类型 在RxJava2中,一般有以下三种异常类型: Checked异常:如 IOException,必须使用 try/catch 块进行处理。 RuntimeException:如 NullPointerException,需要程序员的代码改进避免出现此类异常。此类异常也可以被…

    C 2023年5月23日
    00
  • va_list(),va_start(),va_arg(),va_end() 详细解析

    va_list(),va_start(),va_arg(),va_end() 详细解析 这四个函数在 C 语言中常用于对函数参数数量和类型不定的情况进行处理。下面将详细解析这四个函数。 va_list 它是 C 标准库中的一个类型,通常是一个指针,指向参数列表的起始位置。它用于存储从 va_start() 开始到参数列表最后一个参数数据地址的位置。 va_s…

    C 2023年5月23日
    00
  • 编写C语言程序进行进制转换的问题实例

    编写C语言程序进行进制转换的攻略可以分为以下几个步骤: 1. 确定需要实现的进制转换 要进行进制转换,首先需要确定要转换的进制类型,如十进制、二进制、八进制、十六进制等。可以根据需求选择要转换的进制类型。 2. 设计算法并实现程序代码 经过确定要转换的进制类型,就需要设计转换的算法。通常,将一个进制的数转换为另一个进制的数可以借助中间进制完成,例如将二进制数…

    C 2023年5月23日
    00
  • C语言编程时常犯十八个错误小结

    以下是详细讲解“C语言编程时常犯十八个错误小结”的完整攻略: 一、背景介绍 C语言是一门广泛使用的编程语言,但它也有很多容易犯的错误。这些错误不仅会导致程序的崩溃,还会影响到程序的运行效率。为了帮助C语言入门者避免这些错误,本文会对常见的18个错误进行分析和总结,供大家参考。 二、常见错误及解决方法 1. 数组越界 如果使用一个不存在的数组下标来访问数组中的…

    C 2023年5月23日
    00
  • C++实现停车场管理系统的示例代码

    首先我们需要了解C++实现停车场管理系统需要哪些功能。一般来说,停车场管理系统需要实现以下几个功能: 车辆入场、出场登记,记录车辆基本信息。 管理停车场内的车辆信息,如车位数量、车位状态、收费标准等。 计算车辆停留时间和收费金额。 下面我会针对这些功能,提供一个示例代码: 功能1:车辆入场、出场登记 首先,需要定义一个车辆信息的结构体: // 车辆信息结构体…

    C 2023年5月23日
    00
  • php中JSON的使用与转换

    当我们需要在不同的应用程序之间传输数据时,使用JSON(JavaScript对象表示)是一种非常流行的格式。PHP中的JSON函数使得解析和生成JSON数据非常容易。下面是使用和转换JSON数据的完整攻略。 1. 安装JSON扩展 在使用JSON之前,在PHP中安装JSON扩展是必要的。可以通过以下命令来检测JSON扩展是否已经安装。 php -m | gr…

    C 2023年5月23日
    00
  • C语言用指针传递数据

    C语言中,通过指针传递数据是常见的编程方式,它可以使变量在多个函数中共享,同时也可以避免函数返回值造成的资源浪费等问题。 一、指针的基础语法 指针是存储其他变量地址的变量,可以通过 * 运算符获取该地址存储的值。指针的定义方式如下: int *p; // 定义一个指向 int 类型变量的指针 通过 & 运算符可以获取变量的地址,如: int a = …

    C 2023年5月9日
    00
  • php封装的数据库函数与用法示例【参考thinkPHP】

    下面是详细讲解“php封装的数据库函数与用法示例【参考thinkPHP】”的完整攻略。 1. 什么是php封装的数据库函数? 在php中,我们可以使用一些类和函数来操作数据库,但是这些操作可能会比较繁琐和冗长。因此,我们可以对这些操作进行封装,方便我们使用。封装后的数据库函数可以提供简便的操作方式,使代码更加易读、易维护,也更利于模块化和复用性。 2. ph…

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