算法模版:KMP模板及字符串经典模拟

简介: 算法模版:KMP模板及字符串经典模拟

前言


唤我沈七就好啦。


字符串


KMP:高效查找子串


ne[j] 作用:记录模式串中 j 之前的最长的相等前后辍
这样当出现不匹配的时候后
可以直接跳转到 以前一个字符 结尾的 公共最长前后辍 的前缀 的后面
例如下面这个例子
 s:  abbabfab
 p:  abbabc
当前位置时
s串的'f'与p串的'c'不匹配
kmp的思想是:跳转到 以'c'前面的'b'字符结尾的 公共最长前后辍 的 前缀 的后面 
即 前缀 ab 后面 'b'位置
 s:  abbabfab
 p:   abbabc


#include<bits/stdc++.h>
using namespace std;
const int N = 1e7+10;
int n,m;
int ne[N];
char s[N],p[N];
int main()
{
  cin>>s+1>>p+1;
  n=strlen(s+1),m=strlen(p+1);
  生成 ne【】数组 ,这里利用了动态规划的思想
  for(int i =2 , j = 0 ;  i <= m ; i ++)
  {
     while(j&&p[i]!=p[j+1])j=ne[j];
     if(p[i]==p[j+1])j++;
     ne[i]=j;
  }
  利用ne【】数组,增强匹配效率
  for(int i = 1 , j = 0; i <= n ; i ++)
  {
    while(j&&s[i]!=p[j+1])j=ne[j];
    if(s[i]==p[j+1])j++;
    if(j==m)
    {
      printf("%d\n",i-m+1);
      j=ne[j];
  }
  for(int i = 1 ; i <= m ; i ++)
  printf("%d ",ne[i]);
}


如果读者读到现在对 KMP 的实现原理还是一头雾水,我的建议是 背。

当然 背模板的前提是你最起码 已经 ne【】数组的含义了,至于生成 ne【】数组的过程。

如果你实在对其原理感兴趣 ,可以访问网站 AcWing,那里会有对KMP的讲解 。


验证子串(暴力解法)


#include<bits/stdc++.h>
using namespace std;
const int N = 1e7+10;
int n,m;
int ne[N];
char s[N],p[N];
void kmp(int n,string a,string b)
{
  for(int i = 0 ; i < n ; i ++)
  {
  int j = 0 ,k=i;
  while(a[k++]==b[j++]&&a[k-1]!=0)continue;
  if(j==b.size()+1)
  {
    cout<<b+" is substring of "+a;
    return ; 
  }
  }
  cout<<"No substring";
  return ;
}
int main()
{
   string a,b;
   cin>>a>>b;
   if(a.size()>b.size())
   kmp(a.size(),a,b);
   else
   kmp(b.size(),b,a);
}


字符串经典模拟


删除字符后辍


给定一个单词,如果该单词以er、ly或者ing后缀结尾,则删除该后缀(题目保证删除后缀后的单词长度不为0), 否则不进行任何操作。


将后辍的首字母设成 ‘\0’ 这样就不会打印后辍部分了


#include<stdio.h>
#include<string.h>
int main()
{
  int i,j,m,n;
  char a[100];
  gets(a);
  n=strlen(a);
  if(a[n-2]=='e'&&a[n-1]=='r')
  a[n-2]=0;
  else if(a[n-3]=='i'&&a[n-2]=='n'&&a[n-1]=='g')
  a[n-3]=0; 
  else if(a[n-2]=='l'&&a[n-1]=='y')
  a[n-2]=0;
  printf("%s",a);
  return 0;
}


最长最短单词


给定一句英文句子找出最长与最短的单词。



while(cin>>a)


输入数据 需要


按 Ctrl + Z + 回车


#include<bits/stdc++.h>
using namespace std;
int ans,cnt=99999;
int main()
{
  string a,b,c;
  while(cin>>a)
  {
  if(a.size()>ans) 
  {
    b=a;
    ans=a.size();
  }
  if(a.size()<cnt)
  {
    c=a;
    cnt=a.size();
  }
  }
  cout<<b<<"\n"<<c;
  return 0;
}


翻转单词


输入一个句子(一行),将句子中的每一个单词翻转后输出。


hello world


hello world


#include<bits/stdc++.h>
using namespace std;
int main()
{
  string a,b;
  getline(cin,a);
  for(int i = 0; i <= a.size(); i ++)
  {
  if(a[i]==' '||a[i]==0)
  {
    for(int j = i-1;a[j]!=' '&&j>=0; j --)
    cout<<a[j];
    cout<<" ";
  }
  }
  return 0;
}


完结散花


ok以上就是对 算法模版:数论之约数全家桶 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。


参考文献


https://www.acwing.com/activity/content/19/


相关文章
|
3月前
|
算法
【算法】前缀和——二维前缀和模板题
【算法】前缀和——二维前缀和模板题
|
3月前
|
算法
【算法】滑动窗口——找到字符串中所有字母异位词
【算法】滑动窗口——找到字符串中所有字母异位词
|
1月前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
85 1
两个字符串匹配出最长公共子序列算法
|
1月前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
19 0
|
1月前
|
算法
KMP算法
KMP算法
30 0
|
3月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
3月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
4月前
|
自然语言处理 算法 搜索推荐
字符串相似度算法完全指南:编辑、令牌与序列三类算法的全面解析与深入分析
在自然语言处理领域,人们经常需要比较字符串,这些字符串可能是单词、句子、段落甚至是整个文档。如何快速判断两个单词或句子是否相似,或者相似度是好还是差。这类似于我们使用手机打错一个词,但手机会建议正确的词来修正它,那么这种如何判断字符串相似度呢?本文将详细介绍这个问题。
278 1
|
4月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
120 1
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
3月前
|
算法
KMP算法
KMP算法
28 0
下一篇
无影云桌面