实用算法实践-第 22 篇 字符串匹配

经典字符串匹配算法——KMP算法 KMP算法 KMP算法是一种高效的字符串匹配算法,在传统暴力遍历匹配的基础上做了一定的优化。 首先KMP算法的实现也是使用了回退思想,不过与暴力遍历不同,KMP的回退,是让子串进行匹配,而不是主串。 KMP示例 首先我们来看两个例子来理解KMP算法: 例1: 分别从str的i和sub的j位置处开始匹配: 此时a与c不匹配,如果暴力遍历的话,是i回到到b,j也回到a,重新一轮匹配。而KMP算法,是将子串的j回到第二个a,str[i]与sub[j]重新开始匹配。原因很明显,第二个ab与第一个ab是相同的,因 阅读详情

22.1    Knuth-Morris-Pratt算法

22.1.1   实例

PKU JudgeOnline, 3461, Oulipo.

22.1.2   问题描述

求字符串在另外一个字符串中出现了几次。

22.1.3   输入

3

BAPC

BAPC

AZA

AZAZAZA

VERDI

AVERDXIVYERDIAN

22.1.4   输出

1

3

0

22.1.5   分析

标准的KMP算法解决的问题。将KMP的伪代码一翻译就出来了。

22.1.6   程序

#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int count;
char W[100002];
char T[1000002];
int prefix[1000002];
void computePrefix(char* P, int* prefix)
{
     int m;
     int k;
     int q;
     m = strlen(P) - 1;
     prefix[1] = 0;
     k = 0;
     for(q = 2;q <= m; q++){
         while(k> 0 && P[k + 1] != P[q]){
              k = prefix[k];
         }
         if(P[k+ 1] == P[q])
         {
              k = k + 1;
         }
         prefix[q] = k;
     }
}
void KMP_matcher(char* T, char* P){
     int n;
     int m;
     int q;
     int i;
     n = strlen(T) - 1;
     m = strlen(P) - 1;
     computePrefix(P, prefix);
     q = 0;
     for(i = 1;i <= n; i++){
         while(q> 0 && P[q + 1] != T[i]){
              q = prefix[q];
         }
         if(P[q+ 1] == T[i])
         {
              q = q + 1;
         }
         if(q ==m)
         {
              count ++;
              q = prefix[q];
         }
     }
}
int main()
{
     int time;
     cin >> time;
     for(; time> 0; time--){
         count = 0;
         scanf("%s",&W[1]);
         W[0] = '@';  
         scanf("%s",&T[1]);
         T[0] = '@';
         KMP_matcher(T, W);
         cout << count << endl;
     }
     return 1;
}

22.2    Knuth-Morris-Pratt算法的前缀函数的应用

22.2.1   实例

PKU JudgeOnline, 2752, Seek the Name, Seek the Fame.

22.2.2   问题描述

输出一个字符串中所有前缀、后缀相等的长度。

22.2.3   输入

ababcababababcabab

aaaaa

22.2.4   输出

24 9 18

12 3 4 5

22.2.5   分析

该题的题意是这样的,给若干个字符串,判断该字符串前n个字符和后n个字符是否相同,按从小到大的顺序输出n,比如,给ababab,结果输出2 4 6,再比如ababcababababcabab 输出 2 4 9 18。

我们要根据kmp算法中的next函数来解决这个问题,以ababab为例加以说明:

String:ababab

Next: 0112345

这里根据后面的需要多计算了一位next值。

我们用ababab即作为主串有作为模式串来进行匹配,假设匹配到第7位时不匹配了(下标中1开始),要根据next[7](=5)的值继续匹配:

ababab*

ababab&

ababab*

 ababab

可以由5得出4(5-1)是符合要求的,然后求next[5]=3,即继续这样匹配:

ababab*

 ababab

可以由5得出2(3-1)是符合要求的,然后求next[3]=1,停止循环。

这样,我们依此输出2 4 6即可。

22.2.6   程序

#include <iostream.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

void computePrefix(char* P, int* prefix)

{

     int m;

     int k;

     int q;

     m = strlen(P) - 1;

//   cout <<"m:" << m <<endl;

     prefix[1] = 0;

     k = 0;

//   cout <<prefix[1] << " ";

     for(q = 2;q <= m; q++){

         while(k> 0 && P[k + 1] != P[q]){

              k = prefix[k];

         }

         if(P[k+ 1] == P[q])

         {

              k = k + 1;

         }

         prefix[q] = k;

     //   cout << prefix[q] << "";

     }

     //cout  << endl;

}

char S[400002];

int prefix[400002];

int result[400002];

int main()

{

     int j,index, length;

     while(scanf("%s", &S[1]) != EOF){

         S[0] = '@';

         computePrefix(S, prefix);

         length = strlen(S) - 1;

         j = length;

         index = 0;

         while(1)

         {

              j = prefix[j];

              if(j== 0)

                   break;

              result[++index] = j;

         }

         for(;index > 0; index-- ){

              printf("%d", result[index]);

         }

         cout << length << endl;

     }

     return 1;

}

22.3    实例

PKU JudgeOnline, 2752, Seek the Name, Seek the Fame.

PKU JudgeOnline, 1961, Period.

PKU JudgeOnline, 2406, Power Strings.

PKU JudgeOnline, 3461, Oulipo.

本文章欢迎转载,请保留原始博客链接http://blog.youkuaiyun.com/fsdev/article

字符串匹配算法之KMP算法(图例详解) 阅读详情

相关推荐

字符串匹配算法之暴力做法(朴素算法)

字符串匹配算法之暴力做法(朴素算法)

Sueko的博客 1573

KMP 最模板

转看上串在下串中出现的次数 3 BAPC BAPC AZA AZAZAZA VERDI AVERDXIVYERDIAN#include &lt;iostream&gt;#include &lt;cstring&gt;#include&lt;stdio.h&gt;using namespace std;const int N = 1000002;int next[N];char S[N], T[N]...

najiuzheyangbaacm的博客 221

73、字符串匹配与近似字符串匹配算法详解

本文详细介绍了字符串匹配与近似字符串匹配的核心算法及其应用场景。内容涵盖从简单的O(mn)算法到KMP、Boyer-Moore、Aho-Corasick等高效精确匹配算法,并深入探讨了基于动态规划的编辑距离计算、Hirschberg算法、仿射间隙惩罚及Soundex发音匹配等近似匹配技术。文章还分析了各类算法的时间与空间复杂度,提供了实际应用案例和选择算法的决策流程图,推荐了Strmat、GNU grep、agrep等实用工具,帮助读者根据文本长度、查询频率、容错需求等因素选择最合适的方法。

lg888的博客 89

Oulipo(Hash入门第一题 Hash函数学习)

Hash,一般翻译做散列、杂凑,或音译为哈希,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 这里就只介绍...

308

vLLM 多机多卡推理测试与验证(Kubernetes)vLLM 多机多卡推理 Kubernetes 验证

本文记录在两台 L20 机器,每台机器 4 块 L20 显卡(46G)的环境下,使用 vLLM 部署 Qwen2.5-32B-Instruct-GPTQ-Int4 模型并提供多节点多卡推理服务的过程。服务(Serving)模型服务是指将模型部署到生产环境中,通过 API 或其他接口提供预测服务的过程。【分布式推理与服务】(Distributed Inference and Serving)是指在多个机器或设备之间部署和管理机器学习模型,以高效地处理推理请求并满足大规模服务需求。3、启动 vLLM 服务。

流水_鱼鱼的博客 3459

软件测试工程师笔试题

这里写目录标题全套软件测试面试笔试题(附答案)二、选折三、添空四、简答(资料是搜集整理的,感谢前辈的解题)无1.区别阶段评审的与同行评审2.什么是软件测试3. 简述集成测试的过程4 怎么做好文档测试5 白盒测试有几种方法6 系统测试计划是否需要同行审批,为什么7Alpha 测试与 beta 的区别8 比较负载测试,容量测试和强度测试的区别。性能测试从使用方便的角度来说,9 测试结束的标准是什么?10 描述软件测试活动的生命周期?11 软件的缺陷等级应如何划分? 软件测试工程师笔试题(附答案) 全套软件测试面

m0_46446002的博客 2549

【poj 3461】Oulipo(KMP)

Oulipo Time Limit:1000MS Memory Limit:65536K Total Submissions:47077 Accepted:18734 Description The French author Georges Perec (1936–1982) once wrote a book, La dispariti...

duanghaha的博客 4405

适合初学者的ROS机器人教程(1): Ubuntu下ROS创建自己的包和使用github下载的包

ROS如何创建自己的包 1. 首先创建catkin工作空间(如果你以及有了请忽略) $ mkdir catkin_ws # 创建一个文件夹里面计划放我们的项目,ws是workspace的缩写 $ cd catkin_ws # 将当前工作文件夹切换到catkin_ws这个文件夹 ~/catkin_ws$ catkin_make # 执行catkin_make创建一ROS项目 此时你的catkin_...

@司南牧|知乎|博客|易懂教程|李韬 3244

POJ 3461 KMP

题意:       给你两个字符串,问你串a在串b里面出现了多少次,可以重叠, 比如aaa aaaaa 是3 ,不是1. 思路:       就是在KMP的时候当匹配到比配串的最后一位的时候sum ++就行了,这里提示一下,这个题目说的是可以叠加,如果不可以重叠的,比如aaa aaaaa 输出的应该是1,为为子串不到6个,这样的我们在KMP匹配到匹配串最后一个的时候要把i++ ,j

天使也掉毛 665

【毕设】基于LoRa的物联网控制器:从原理图到PCB的完整硬件设计指南

本文提供了一份完整的基于LoRa的物联网控制器硬件设计指南,涵盖从系统框图、原理图设计到PCB布局布线的全流程。详细讲解了电源电路、单片机最小系统、信号接口以及LoRa无线模块等核心模块的设计要点与抗干扰技巧,并分享了实用的调试心得,旨在帮助电子、物联网专业学生顺利完成毕业设计,掌握低功耗远距离物联网节点的硬件开发实践。

weixin_42126677的博客 306

华为OD机试双机位C卷:采购订单 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 采购订单,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,并提供在线OJ模拟做题。华为OD机试真题【采购订单】

qq_45776114的博客 3534

字符串匹配—KMP算法

这种类型字符串题目都可以采用暴力解法,套两层for循环也可以实现,但是时间复杂度太大,采用KMP算法之后,时间复杂度更低。所以掌握KMP算法还是有意义的

Hhjhj255的博客 872

【WRF数据准备】土地利用数据-MODIS MCD12Q1数据下载及制备

【WRF数据准备】MODIS静态地理数据下载及制备

WW、forever的博客 3413

字符串匹配算法

第一篇随笔,开始写博客生涯。写程序这么长时间,突然发现也要总结与积累。原来想第一篇博文是关于以前写的代码研究,发现还需要整理。这样,先发表一篇关于字符串 匹配的文章。就这样啦!         字符串匹配主要是关于模式串与主串匹配的问题。关于这个问题,有很多方法。网上也有不少例子,借鉴了不少,以下就介绍下面几种算法。           (1)BF算法(常规算法)  

佛曰不可说 1000

【2025国赛A题】A题烟幕干扰弹的投放策略思路+代码+论文

【2025国赛A题】A题烟幕干扰弹的投放策略思路+代码+论文

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 866

ARM CoreLink 系列 5.1.1 -- CI-700 System Address Map 】

所有的CHI 命令都包含一个 Source ID 和 Target ID, 其中 Source ID 可以来自于 RN Node, Target ID 可以来自于HN node或者其他 SN node. 其中 Target ID 是通过 SAM解析传入的地址得到的。对于 CI-700中的所有 RN Node 中的 SAM 多会进行配置,因为RN Node 访问的是整个地址空间,不同的地址空间会有不同的属性(I/O, DRAM),所以会对RN SAM 配置多个不同属性的区域。

CodingCos的博客 771

数据结构与算法系列22--字符串匹配算法

字符串匹配这样的函数,在很多编程语言中都提供了字符串的查找算法,那它底层具体是怎么实现的呢? 字符串的匹配算法有很多,简单一点的:BF算法和RF算法。高级一点的,BM算法和KMP算法。 ...

Lin的博客 339

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

字符串匹配算法总结 (分析及Java实现)

字符串模式匹配算法(string searching/matching algorithms) 顾名思义,就是在一个文本或者较长的一段字符串中,找出一个或多个指定字符串(Pattern),并返回其位置。这类算法属基础算法,各种编程语言都将其包括在自带的String类函数中,而且由之衍生出来的正则表达式也是必须掌握的一种概念和编程技术。

chndata的专栏 2万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

字符串匹配KMP算法

一、strstr    嵌入式软件开发时会在某个长字符串中,检索出现指定字符串标识的需求,最常用的库函数就是strstr。其源码有很多版本,常用经典实现方式: char *strstr(const char *str1, const char *str2) { char *cp = (char *) str1; char *s1, *s2; if (!*str2) return ((char *) str1); while (*cp) { s1

123 1万+

【总结】关于字符串匹配算法研究

(1)BF算法(常规算法)          BF算法就是最笨的算法,一个一个进行匹配。这里采用后缀匹配算法。其实与正常的BF算法想法差不多。只不过为了与第四种算法相对应,就用后缀匹配算法代替BF算法。          从网上搞些图(自己实在不想自己画图)                     从后面开始进行匹配。当不匹配时,子串整体向右偏移一个单位,再与主串进行比较。从而不断进行

YSBJ123的博客 991

关于字符串匹配算法研究

第一篇随笔,开始写博客生涯。写程序这么长时间,突然发现也要总结与积累。原来想第一篇博文是关于以前写的代码研究,发现还需要整理。这样,先发表一篇关于字符串 匹配的文章。就这样啦! 字符串匹配主要是关于模式串与主串匹配的问题。关于这个问题,有很多方法。网上也有不少例子,借鉴了不少,以下就介绍下面几种算法。 (1)BF算法(常规算法)...

JohnsonZhu2014的博客 356
上一篇: 实用算法实现-第 21 篇 每对顶点间的最短路径
下一篇: 实用算法实现-第 23 篇 最大流
存储李希
博客等级 码龄15年 418粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值