KMP算法的C#实现方法

KMP算法的C#实现方法

概述

KMP算法是一种字符串匹配算法,可以用于快速查找一个字符串是否包含另一个字符串,或者在多个字符串中查找某个子串。该算法的基本思想是尽可能地避免重复匹配。通过预处理模式串的匹配数组,我们可以在匹配过程中跳过已经匹配过的部分,从而提高匹配效率。

算法实现

步骤一:求取模式串的匹配数组

首先,我们需要对模式串进行预处理,求取出模式串的匹配数组 $next$,该数组记录了当前位置之前的子串中最长的相等前缀后缀的长度。

private static void getNext(string pattern, int[] next)
{
    int i = 0, j = -1;
    next[0] = -1;

    // 循环计算匹配数组
    while(i < pattern.Length - 1)
    {
        if(j == -1 || pattern[i] == pattern[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }
}

步骤二:匹配主串和模式串

在匹配主串和模式串时,如果当前字符匹配成功,则进行下一位字符的匹配;否则,根据模式串的匹配数组,向前跳过一定长度的字符,继续匹配。

public static int KMP(string text, string pattern)
{
    int i = 0, j = 0;
    int[] next = new int[pattern.Length];

    // 求取匹配数组
    getNext(pattern, next);

    // 匹配主串和模式串
    while(i < text.Length && j < pattern.Length)
    {
        if(j == -1 || text[i] == pattern[j])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];
        }
    }

    // 匹配成功,返回匹配的起始位置;否则,返回 -1
    if(j == pattern.Length)
    {
        return i - j;
    }
    else
    {
        return -1;
    }
}

示例

假设我们要在字符串 "ABCABCABCABCDABCMN" 中查找子串 "ABCABD",则代码实现如下:

string text = "ABCABCABCABCDABCMN";
string pattern = "ABCABD";

int index = KMP(text, pattern);
if(index != -1)
{
    Console.WriteLine("找到了,起始位置是:" + index);
}
else
{
    Console.WriteLine("没找到!");
}

假设我们要在多个字符串中查找某个子串,则代码实现如下:

string[] texts = {"ABCABCABCABCDABCMN", "DEFGABCABC", "HIJKLM"};
string pattern = "ABCABD";

foreach(string text in texts)
{
    int index = KMP(text, pattern);
    if(index != -1)
    {
        Console.WriteLine("在字符串" + text + "中找到了,起始位置是:" + index);
    }
    else
    {
        Console.WriteLine("在字符串" + text + "中没找到!");
    }
}

总结

KMP算法是一种高效的字符串匹配算法,可以在 $O(n+m)$ 的时间复杂度内完成匹配过程,其中 $n$ 和 $m$ 分别是主串和模式串的长度。实现该算法的关键在于预处理模式串的匹配数组,通过该数组在匹配过程中避免重复匹配,从而提高匹配效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:KMP算法的C#实现方法 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • 在C#中使用SQLite数据库

    轻量级桌面程序数据库不太适合用SQLServer、MySQL之类的重量级数据库,嵌入式数据库更好。在对比Access、SQLite、Firebird数据库后发现SQLite较另外两个有较多优点。 环境:.NET Framework 3.5、windows11 64位、Visual Studio 2010. C#使用SQLite需要从SQLite官网下载DLL…

    C# 2023年4月27日
    00
  • C#利用性能计数器监控网络状态

    下面是C#利用性能计数器监控网络状态的完整攻略: 准备工作 在开始使用性能计数器监控网络状态之前,需要做一些准备工作。首先,需要确保计算机已经安装了PerformanceCounter类所需的性能计数器。如果没有安装,可以在计算机管理控制台的“性能监视器”中打开“性能监视器”窗口,在左侧的树形菜单中选择“计算机名” ->“性能监视器” ->“实时…

    C# 2023年5月15日
    00
  • asp实现二进制字符串转换为Unicode字符串

    实现二进制字符串转换为Unicode字符串,可以通过以下步骤来完成: 将二进制字符串转换为byte数组。可以通过将二进制字符串每8位作为一个byte元素,将这些byte元素组成一个byte数组,来实现二进制字符串转换为byte数组。 示例1: 假设有以下二进制字符串:01100001011100100111001101110100 按照每8位作为一个byte…

    C# 2023年6月7日
    00
  • C#新手常犯的错误汇总

    C#新手常犯的错误汇总 前言 C#作为一门流行的编程语言,吸引了很多新手程序员的青睐。但是,在学习和练习过程中,新手程序员常常会犯一些错误。本文将总结并详细讲解C#新手程序员常犯的错误,并提供完整的解决方案。 1. 变量的生命周期不清楚 在C#中,变量的生命周期是很重要的一个概念。如果不清楚变量的生命周期,可能会导致程序出现奇怪的问题。 错误示例 publi…

    C# 2023年5月15日
    00
  • 深入了解C#设计模式之订阅发布模式

    欢迎来到深入了解C#设计模式之订阅发布模式的完整攻略。本攻略将会带你深入探索这种设计模式,包括其基础知识、应用场景、实现步骤、示例、优缺点等方面。 一、订阅发布模式基础知识 1.1 什么是订阅发布模式? 订阅发布模式(Publish/Subscribe Pattern)是一种事件处理模式,也叫做消息机制或者观察者模式。该模式定义了一种对象间的一对多的关系,让…

    C# 2023年5月15日
    00
  • gridview实现服务器端和客户端全选的两种方法分享

    首先,我们需要了解 GridView 是什么。GridView 是 ASP.NET WebForms 中常用的数据控件,用于将数据以表格的形式展示出来。在 GridView 中,一般会有多个 CheckBox 控件用于实现表格中数据的多选和全选功能。 接下来,我将介绍两种实现 GridView 的服务器端和客户端全选的方法。 方法一:使用事件处理程序实现全选…

    C# 2023年6月8日
    00
  • c#委托与事件(详解)

    C#委托与事件(详解) 什么是委托? 在C#中,委托是一个类,用于指向和调用一个或多个方法。可以将委托看做是方法的类型。通过委托,我们可以在运行时确定要调用哪个方法,而无需提前确定调用哪个方法。 如何定义委托? 在C#中,委托的定义非常简单,只需使用delegate关键字即可。 delegate 返回类型 委托名称(参数列表); 其中, 返回类型:委托指向方…

    C# 2023年6月1日
    00
  • 使用C#9中records作为强类型ID的实例教程

    使用C#9中records作为强类型ID可以让程序变得更加健壮和安全,让我们来一步步学习如何使用它。 什么是records? records是C#9的新特性,它是值类型,用来表示不可变的数据对象,其简洁的语法使得代码更加易读、易写。 在records类型中,可以定义只读属性、可写属性和自动属性,但是不允许定义私有控制器,因为records类型是不可变的。 下…

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