C语言经典算法之朴素模式匹配算法

目录

前言

A.建议

B.简介

一 代码实现

二 时空复杂度

A.时间复杂度(Time Complexity):

B.空间复杂度(Space Complexity):

三 优缺点

A.优点:

B.缺点:

四 现实中的应用


前言

A.建议

1.学习算法最重要的是理解算法的每一步,而不是记住算法。

2.建议读者学习算法的时候,自己手动一步一步地运行算法。

tips:文中的(如果有)对数,则均以2为底数

B.简介

朴素模式匹配算法(Naive String Matching Algorithm),也称为简单字符串搜索或暴力匹配算法,是一种直观且易于理解的在主串中查找子串的方法。该算法的基本思想是从主串的第一个字符开始,与子串的第一个字符进行比较,如果相等,则继续比较下一个字符,直到子串的所有字符都被逐一匹配或者在某个位置不匹配为止。一旦发生不匹配,算法会将主串的指针回溯到上一个未匹配字符之后的位置,然后再次尝试从这个新位置开始匹配。

一 代码实现

#include 
#include 

// 函数声明
int NaivePatternMatch(char *text, char *pattern);

int main() {
    char text[] = "I am looking for a pattern in this text";
    char pattern[] = "pattern";

    int index = NaivePatternMatch(text, pattern);
    if (index != -1) {
        printf("Pattern found at index: %d\n", index);
    } else {
        printf("Pattern not found in the text.\n");
    }

    return 0;
}

// 朴素模式匹配函数
int NaivePatternMatch(char *text, char *pattern) {
    int tlen = strlen(text);
    int plen = strlen(pattern);

    // 遍历文本中的所有可能起始位置
    for (int i = 0; i <= tlen - plen; ++i) {
        // 比较当前起始位置后plen个字符是否与模式串相同
        int j;
        for (j = 0; j < plen; ++j) {
            if (text[i + j] != pattern[j]) {
                break; // 如果发现不匹配,则跳出内层循环
            }
        }

        // 如果完整匹配了整个模式串,则返回当前起始位置
        if (j == plen) {
            return i;
        }
    }

    // 没有找到匹配,则返回-1
    return -1;
}

在这个程序中,NaivePatternMatch 函数接受两个参数:一个是主串(text),另一个是要查找的模式串(pattern)。它通过双重循环遍历主串的所有可能的子串,并逐个字符地与模式串进行比较。当找到完全匹配时,函数返回主串中匹配开始的索引;如果没有找到匹配,则返回 -1。这种算法的时间复杂度为 O(n*m),其中 n 是主串的长度,m 是模式串的长度。在实际应用中,对于长文本和较长的模式串,朴素模式匹配的效率较低,因为存在大量的重复计算。KMP算法就是用来优化这种情况的一个经典算法。

二 时空复杂度

A.时间复杂度(Time Complexity)

朴素模式匹配算法的时间复杂度是 O(n * m),其中n 是主串的长度,m 是模式串的长度。因为算法通过双重循环实现:外层循环遍历主串的所有可能起始位置,内层循环则逐个比较主串与模式串的字符是否相等。最坏情况下,需要对每个子串都进行完整的m 个字符的比较,因此总的比较次数最多为n * m次。

B.空间复杂度(Space Complexity)

朴素模式匹配算法的空间复杂度是 O(1)。在算法执行过程中,只使用了几个临时变量存储索引值,并未使用与输入字符串长度相关的额外空间。所以,它是一种原地操作算法,空间复杂度较低。

三 优缺点

A.优点:

  1. 简单易懂:朴素模式匹配算法的逻辑非常直观,易于理解和实现,只需要使用简单的循环和条件判断就能完成。

  2. 无需预处理:在匹配过程中不需要对主串或模式串进行任何预处理,可以直接开始匹配过程。

  3. 空间效率高:该算法的空间复杂度低,通常为 O(1),因为它仅需存储几个变量来跟踪比较的位置,并不依赖于输入文本或模式串的长度。

B.缺点:

  1. 时间效率低:朴素模式匹配的主要缺点在于其时间效率不高,具有较高的时间复杂度 O(n * m),其中 n 是主串长度,m 是模式串长度。当模式串与主串部分匹配后发生失配时,算法会将主串指针回溯到上次比较起始位置之后的一个字符重新开始匹配,这样会导致大量的重复计算,尤其是在模式串较短且在主串中频繁出现的情况下。

  2. 不适用于大数据集:由于上述原因,当面对大文本数据时,该算法性能极差,无法有效应对大规模字符串匹配问题。

  3. 未利用已知信息:对于已经部分匹配但最终失败的情况,算法没有保留任何有用的信息以减少后续匹配的冗余操作,比如 KMP 算法引入了前缀函数和部分匹配表的概念来解决这个问题。

四 现实中的应用

  1. 基础教育与初阶编程教学

    • 朴素模式匹配算法概念简单直观,易于理解,常被用于计算机科学和数据结构的基础课程中,作为介绍字符串模式匹配问题的入门算法,帮助学生掌握基本的逐字符比较思想。
  2. 小型数据处理

    • 当处理的数据量不大,即主串和模式串长度均较短时,朴素算法因其实现简单,无需额外预处理而具有实用性。在这种情况下,算法的整体运行速度可能不会成为性能瓶颈。
  3. 一次性或非频繁查询

    • 对于那些不需要高效实时响应、只是偶尔进行一次或几次查找的情况,如在一些脚本文件、日志文件等中查找特定模式,使用朴素算法也能达到目的,且开发成本较低。
  4. 快速原型开发与验证

    • 在软件开发初期阶段,开发者可能会先用朴素模式匹配算法来验证模式匹配的基本逻辑和功能正确性,之后再考虑是否替换为更高效的算法以提高性能。
  5. 受限环境下的应用

    • 在内存有限或计算资源受限的环境中,比如嵌入式系统,复杂的预处理或者空间消耗较大的算法可能不适合使用,这时朴素算法可以作为一个轻量级的选择。

你可能感兴趣的:(C语言经典算法,算法)