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;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/323927.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阳光抑郁症测试

大部分人对抑郁症的理解&#xff0c;就是每天无精打采&#xff0c;死气沉沉&#xff0c;可实际上&#xff0c;还有一种阳光抑郁症&#xff0c;完全不是这个样子。这种抑郁症的人&#xff0c;做事情非常有活力&#xff0c;魅力十足&#xff0c;给人感觉十分有自信&#xff0c;但…

MATLAB读取图片并转换为二进制数据格式

文章目录 前言一、MATLAB 文件读取方法1、文本文件读取2、二进制文件读取3、 图像文件读取4、其他文件读取 二、常用的图像处理标准图片链接三、MATLAB读取图片并转换为二进制数据格式1、matlab 源码2、运行结果 前言 本文记录使用 MATLAB 读取图片并转换为二进制数据格式的方…

国科大软件安全原理期末复习笔记

1 软件安全总论 1.软件的三大特性&#xff1a;复杂性、互连性、可扩展性&#xff1b; 2.基本概念&#xff1a;缺陷、漏洞、风险 缺陷&#xff08;bug&#xff09;&#xff1a;软件在设计和实现上的错误&#xff1b;漏洞&#xff08;vulnerability&#xff09;&#xff1a;漏洞…

专访美国Foley Hoag律师事务所合伙人:2024量子计算颠覆制药业

人物介绍&#xff1a;美国Foley Hoag 律师事务所的合伙人Erik Huestis&#xff0c;兼任该事务所技术行业小组的联席主席&#xff0c;近期于采访中深入探讨了在未来一年&#xff0c;生命科学和生物技术行业将如何运用量子计算技术的相关问题。 ​编辑丨慕一 编译/排版丨琳梦 卉…

OPT(erlang)打造一套缓存系统(一)

缓存的设计 这个简易缓存存储的是键/值对&#xff0c;其中键与键之间不得重复&#xff0c;并且每个键只能映射到一个值。这个设计背后的核心思想是为写人缓存的每一个值都分配一个独立的存储进程再将对应的键映射至该进程。你可能会对这种为每个值分配一个进程的设计感到惊讶&…

深度学习代码学习(一文真正看懂卷积层的代码定义)

一维卷积: 将n行3列升维到n行6列。&#xff08;原因&#xff1a;卷积核为6个&#xff09; *表示点乘 Linear线性层&#xff1a; &#xff08;通过矩阵计算改变输入输出特征向量的维度&#xff09; Pytorch nn.Linear的基本用法与原理详解-CSDN博客 pytorch初学笔记&#…

云服务器部署Stable Diffusion Webui从0到1总结:反复重启+循环debug

文章目录 在学校服务器部署Stable Diffusion Webui&#xff08;一&#xff09;准备工作&#xff08;二&#xff09;环境配置&#xff08;三&#xff09;git拉取项目到本地&#xff08;四&#xff09;运行项目 遇到的问题&#xff1a;&#xff08;一&#xff09;使用git clone时…

【C++干货铺】会旋转的二叉树——AVLTree

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 前言 AVL树 AVL树的概念 AVL树结点的定义 AVL树的插入 寻找插入结点的位置 修改平衡因子 AVL树的旋转 右单旋 左单旋 先右旋再左旋 先左旋再右旋 AVL树…

Bazel

简介&#xff1a; Bazel 是 google 研发的一款开源构建和测试工具,也是一种简单、易读的构建工具。 Bazel 支持多种编程语言的项目&#xff0c;并针对多个平台构建输出。 高级构建语言&#xff1a;Bazel 使用一种抽象的、人类可读的语言在高语义级别上描述项目的构建属性。与其…

数据库结构文档生成方法二(EZDML)

EZDML 下载链接&#xff1a;EZDML - 下载 我们常用的是数据建模有PowerDesigner,EZDML也是一款数据建模工具&#xff0c;而且功能很多&#xff0c;除了生成sql&#xff0c;还可以生成前端后端代码等等。 我们直接下载最新版后点击安装&#xff0c;打开后会默认打开示例&#…

计划——不做计划

今天想讲一下我做计划这件事。 2024 年已经过了两个星期了&#xff0c;毕竟自己也到了一个新的阶段&#xff0c;想着也可以搞个计划&#xff0c;写写自己未来一年计划做的事情。 但回忆了过去这半年来我所做的计划&#xff0c;我的双手抚摸着键盘&#xff0c;迟迟动不了手。 …

Linux网络编程---IP 地址格式转换函数

Linux网络编程—IP 地址格式转换函数 我们更容易阅读的IP地址是以点分十进制表示的&#xff0c;例如&#xff1a;192.168.5.10 &#xff0c;这是一种字符串的形式&#xff0c;但是计算器所需要的IP地址是以二进制进行表示&#xff0c;这便需要我们在点分十进制字符串和二进制地…

Jmeter 测试脚本录制器-HTTP 代理服务器

Jmeter 测试脚本录制器-HTTP 代理服务器 Jmeter 配置代理服务器代理服务器获取请求地址示例图配置步骤 浏览器配置代理Google 浏览器插件配置代理windows 本地网络配置代理 启动录制&#xff0c;生成证书生成证书导入证书Jmeter 配置证书 浏览器点击页面&#xff0c;录制请求地…

基于Springboot的善筹网(众筹网-有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的善筹网(众筹网-有报告)。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring S…

5 - 声明式事务

传统事务流程&#xff1a; Connection connection JdbcUtils.getConnection(); try {//1. 先设置事务不要自动提交connection.setAutoCommit(false);//2. 进行各种 crud//多个表的修改&#xff0c;添加 &#xff0c;删除select from 商品表 > 获取价格//修改用户余额updat…

Jetbrains ai assistant激活后仍无法使用,怎么回事?

用正式的ai assistant激活码激活后仍然无法使用 首先获取了ai assistant激活码&#xff0c;激活后如下 地址&#xff1a;https://web.52shizhan.cn 上图是已经激活成功了&#xff0c;但是在右侧这里打开ai assistant不可用 点击开始使用ai assistant 出错 以上是用了ai as…

排序——归并排序

文章目录 基本思想递归版本思路代码实现 非递归版思路代码实现 特性结果演示 基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子…

智能合约介绍

莫道儒冠误此生&#xff0c;从来诗书不负人 目录 一、什么是区块链智能合约? 二、智能合约的发展背景 三、智能合约的优势 四、智能合约的劣势 五、一些关于智能合约的应用 总结 一、什么是区块链智能合约? 智能合约&#xff0c;是一段写在区块链上的代码&#xff0c;一…

HNU-算法设计与分析-实验2

算法设计与分析实验2 计科210X 甘晴void 202108010XXX 目录 文章目录 算法设计与分析<br>实验21 用动态规划法实现0-1背包问题重述想法代码验证算法分析 2 用贪心算法求解背包问题问题重述想法代码验证算法分析 3 半数集问题&#xff08;实现题2-3&#xff09;问题重述…