当前位置: 首页 > news >正文

C#,字符串匹配(模式搜索)AC(Aho Corasick)算法的源代码

Aho-Corasick算法简称AC算法,也称为AC自动机(Aho-Corasick)算法,1975年产生于贝尔实验室The Bell Labs,是一种用于解决多模式字符串匹配的经典算法之一。

the Bell Lab 

本文的运行效果:

AC算法以模式树(字典树)Trie、广度优先策略和KMP模式匹配算法为核心内容。

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// Aho_Corasick 算法
    /// </summary>
    public static partial class PatternSearch
    {
        private static int MAXS = 512;
        private static int MAXC = 26;

        private static int[] outt = new int[MAXS];

        private static int[] f = new int[MAXS];

        private static int[,] g = new int[MAXS, MAXC];

        private static int buildMatchingMachine(string[] arr, int k)
        {
            for (int i = 0; i < outt.Length; i++)
            {
                outt[i] = 0;
            }

            for (int i = 0; i < MAXS; i++)
            {
                for (int j = 0; j < MAXC; j++)
                {
                    g[i, j] = -1;
                }
            }

            int states = 1;
            for (int i = 0; i < k; ++i)
            {
                string word = arr[i];
                int currentState = 0;

                for (int j = 0; j < word.Length; ++j)
                {
                    int ch = word[j] - 'A';
                    if (g[currentState, ch] == -1)
                    {
                        g[currentState, ch] = states++;
                    }
                    currentState = g[currentState, ch];
                }

                outt[currentState] |= (1 << i);
            }

            for (int ch = 0; ch < MAXC; ++ch)
            {
                if (g[0, ch] == -1)
                {
                    g[0, ch] = 0;
                }
            }

            for (int i = 0; i < MAXC; i++)
            {
                f[i] = 0;
            }

            Queue<int> q = new Queue<int>();
            for (int ch = 0; ch < MAXC; ++ch)
            {
                if (g[0, ch] != 0)
                {
                    f[g[0, ch]] = 0;
                    q.Enqueue(g[0, ch]);
                }
            }

            while (q.Count != 0)
            {
                int state = q.Peek();
                q.Dequeue();

                for (int ch = 0; ch < MAXC; ++ch)
                {
                    if (g[state, ch] != -1)
                    {
                        int failure = f[state];
                        while (g[failure, ch] == -1)
                        {
                            failure = f[failure];
                        }

                        failure = g[failure, ch];
                        f[g[state, ch]] = failure;

                        outt[g[state, ch]] |= outt[failure];

                        q.Enqueue(g[state, ch]);
                    }
                }
            }
            return states;
        }

        private static int findNextState(int currentState, char nextInput)
        {
            int answer = currentState;
            int ch = nextInput - 'A';

            while (g[answer, ch] == -1)
            {
                answer = f[answer];
            }
            return g[answer, ch];
        }

        public static List<int> Aho_Corasick_Search(string text, string pattern, int k = 1)
        {
            List<int> matchs = new List<int>();

            string[] arr = new string[1] { pattern };
            buildMatchingMachine(arr, k);

            int currentState = 0;

            for (int i = 0; i < text.Length; ++i)
            {
                currentState = findNextState(currentState, text[i]);

                if (outt[currentState] == 0)
                {
                    continue;
                }

                for (int j = 0; j < k; ++j)
                {
                    if ((outt[currentState] & (1 << j)) > 0)
                    {
                        matchs.Add((i - arr[j].Length + 1));
                    }
                }
            }

            return matchs;
        }
    }
}

POWER BY TRUFFER.CN

using System;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{/// <summary>/// Aho_Corasick 算法/// </summary>public static partial class PatternSearch{private static int MAXS = 512;private static int MAXC = 26;private static int[] outt = new int[MAXS];private static int[] f = new int[MAXS];private static int[,] g = new int[MAXS, MAXC];private static int buildMatchingMachine(string[] arr, int k){for (int i = 0; i < outt.Length; i++){outt[i] = 0;}for (int i = 0; i < MAXS; i++){for (int j = 0; j < MAXC; j++){g[i, j] = -1;}}int states = 1;for (int i = 0; i < k; ++i){string word = arr[i];int currentState = 0;for (int j = 0; j < word.Length; ++j){int ch = word[j] - 'A';if (g[currentState, ch] == -1){g[currentState, ch] = states++;}currentState = g[currentState, ch];}outt[currentState] |= (1 << i);}for (int ch = 0; ch < MAXC; ++ch){if (g[0, ch] == -1){g[0, ch] = 0;}}for (int i = 0; i < MAXC; i++){f[i] = 0;}Queue<int> q = new Queue<int>();for (int ch = 0; ch < MAXC; ++ch){if (g[0, ch] != 0){f[g[0, ch]] = 0;q.Enqueue(g[0, ch]);}}while (q.Count != 0){int state = q.Peek();q.Dequeue();for (int ch = 0; ch < MAXC; ++ch){if (g[state, ch] != -1){int failure = f[state];while (g[failure, ch] == -1){failure = f[failure];}failure = g[failure, ch];f[g[state, ch]] = failure;outt[g[state, ch]] |= outt[failure];q.Enqueue(g[state, ch]);}}}return states;}private static int findNextState(int currentState, char nextInput){int answer = currentState;int ch = nextInput - 'A';while (g[answer, ch] == -1){answer = f[answer];}return g[answer, ch];}public static List<int> Aho_Corasick_Search(string text, string pattern, int k = 1){List<int> matchs = new List<int>();string[] arr = new string[1] { pattern };buildMatchingMachine(arr, k);int currentState = 0;for (int i = 0; i < text.Length; ++i){currentState = findNextState(currentState, text[i]);if (outt[currentState] == 0){continue;}for (int j = 0; j < k; ++j){if ((outt[currentState] & (1 << j)) > 0){matchs.Add((i - arr[j].Length + 1));}}}return matchs;}}
}

相关文章:

C#,字符串匹配(模式搜索)AC(Aho Corasick)算法的源代码

Aho-Corasick算法简称AC算法&#xff0c;也称为AC自动机(Aho-Corasick)算法&#xff0c;1975年产生于贝尔实验室&#xff08;The Bell Labs&#xff09;&#xff0c;是一种用于解决多模式字符串匹配的经典算法之一。 the Bell Lab 本文的运行效果&#xff1a; AC算法以模式树…...

【网络取证篇】Windows终端无法使用ping命令解决方法

【网络取证篇】Windows终端无法使用ping命令解决方法 以Ping命令为例&#xff0c;最近遇到ping命令无法使用的情况&#xff0c;很多情况都是操作系统"环境变量"被改变或没有正确配置导致—【蘇小沐】 目录 1、实验环境&#xff08;一&#xff09;无法ping命令 &a…...

electron+vue网页直接播放RTSP视频流?

目前大部分摄像头都支持RTSP协议&#xff0c;但是在浏览器限制&#xff0c;最新版的浏览器都不能直接播放RTSP协议&#xff0c;Electron 桌面应用是基于 Chromium 内核的&#xff0c;所以也不能直接播放RTSP&#xff0c;但是我们又有这个需求怎么办呢&#xff1f; 市场上的方案…...

【Delphi 基础知识 19】Assigned的用法

在Delphi中&#xff0c;Assigned 是一个用于检查指针是否已分配内存的函数。它通常用于检查对象或指针是否已经被分配内存&#xff0c;以避免在未分配内存的情况下引用或操作它。 以下是 Assigned 的一些用法示例&#xff1a; 检查对象是否已分配内存&#xff1a; varMyObject…...

多线程在编程中的重要性有什么?并以LabVIEW为例进行说明

多线程在编程中的重要性体现在以下几个方面&#xff1a; 并行处理&#xff1a; 多线程允许程序同时执行多个任务&#xff0c;这在现代多核心处理器上尤其重要。通过并行处理&#xff0c;可以显著提高程序的执行效率和响应速度。 资源利用最大化&#xff1a; 通过多线程&#x…...

K8S---kubectl top

一、简介 该命令类似于linux–top命令,用于显示node和pod的CPU和内存使用情况 二、命令行 1、help命令 k top --help Display resource (CPU/memory) usage. The top command allows you to see the resource consumption for nodes or pods. This command requires Metri…...

Linux部署前后端项目

部署SpringBoot项目 创建SpringBoot项目 先确保有一个可以运行的springboot项目&#xff0c;这里就记录创建项目的流程了&#xff0c;可以自行百度。 命令行启动 2.1、在linux中&#xff0c;我是在data目录下新创建的一个project目录&#xff08;此目录创建位置不限制&…...

一文搞懂系列——Linux C线程池技术

背景 最近在走读诊断项目代码时&#xff0c;发现其用到了线程池技术&#xff0c;感觉耳目一新。以前基本只是听过线程池&#xff0c;但是并没有实际应用。对它有一丝的好奇&#xff0c;于是趁这个机会深入了解一下线程池的实现原理。 线程池的优点 线程池出现的背景&#xf…...

stable diffusion代码学习笔记

前言&#xff1a;本文没有太多公式推理&#xff0c;只有一些简单的公式&#xff0c;以及公式和代码的对应关系。本文仅做个人学习笔记&#xff0c;如有理解错误的地方&#xff0c;请指出。 本文包含stable diffusion入门文献和不同版本的代码。 文献资源 本文学习的代码&…...

腾讯云服务器怎么买?两种购买方式更省钱

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…...

基于SpringBoot自定义控制是否需要开启定时功能

在基于SpringBoot的开发过程中&#xff0c;有时候会在应用中使用定时任务&#xff0c;然后服务器上启动定时任务&#xff0c;本地就不需要开启定时任务&#xff0c;使用一个参数进行控制&#xff0c;通过查资料得知非常简单。 参数配置 在application-dev.yml中加入如下配置 …...

“确定要在不复制其属性的情况下复制此文件?”解决方案(将U盘格式由FAT格式转换为NTFS格式)

文章目录 1.问题描述2.问题分析3.问题解决3.1 方法一3.2 方法二3.3 方法三 1.问题描述 从电脑上复制文件到U盘里会出现“确定要在不复制其属性的情况下复制此文件&#xff1f;”提示。 2.问题分析 如果这个文件在NTFS分区上&#xff0c;且存在特殊的安全属性。那么把它从NT…...

视频监控系统EasyCVR如何通过调用API接口查询和下载设备录像?

智慧安防平台EasyCVR是基于各种IP流媒体协议传输的视频汇聚和融合管理平台。视频流媒体服务器EasyCVR采用了开放式的网络结构&#xff0c;支持高清视频的接入和传输、分发&#xff0c;平台提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联…...

15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条

15.鸿蒙HarmonyOS App(JAVA)进度条与圆形进度条 progressBar2.setIndeterminate(true);//设置无限模式,运行查看动态效果 //创建并设置无限模式元素 ShapeElement element new ShapeElement(); element.setBounds(0,0,50,50); element.setRgbColor(new RgbColor(255,0,0)); …...

【FastAPI】路径参数

路径参数 from fastapi import FastAPIapp FastAPI()app.get("/items/{item_id}") async def read_item(item_id):return {"item_id": item_id}其中{item_id}就为路径参数 运行以上程序当访问 &#xff1a;http://127.0.0.1:8000/items/fastapi时候 将会…...

【docker笔记】DockerFile

DockerFile Docker镜像结构的分层 镜像不是一个单一的文件&#xff0c;而是有多层构成。 容器其实是在镜像的最上面加了一层读写层&#xff0c;在运行容器里做的任何文件改动&#xff0c;都会写到这个读写层。 如果删除了容器&#xff0c;也就是删除了其最上面的读写层&…...

React项目搭建流程

第一步 利用脚手架创建ts类型的react项目&#xff1a; 执行如下的命令&#xff1a;create-react-app myDemo --template typescript &#xff1b; 第二步 清理项目目录结构&#xff1a; src/ index.tsx, app.txs, react-app-env.d.ts public/index.ht…...

QT DAY1作业

1.QQ登录界面 头文件代码 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QIcon> #include <QLabel> #include <QPushButton> #include <QMovie> #include <QLineEdit>class MyWidget : public QWidget {Q_OBJECTpu…...

Java后端开发——Mybatis实验

文章目录 Java后端开发——Mybatis实验一、MyBatis入门程序1.创建工程2.引入相关依赖3.数据库准备4.编写数据库连接信息配置文件5.创建POJO实体6.编写核心配置文件和映射文件 二、MyBatis案例&#xff1a;员工管理系统1.在mybatis数据库中创建employee表2.创建持久化类Employee…...

【UE Niagara 网格体粒子系列】02-自定义网格

目录 步骤 一、创建自定义网格体 二、创建Niagara系统 步骤 一、创建自定义网格体 1. 打开Blender&#xff0c;按下ShiftA来创建一个平面 将该平面旋转90 导出为fbx 设置导出选定的物体&#xff0c;这里命名为“SM_PlaneFaceCamera.fbx” 按H隐藏刚才创建的平面&#x…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...