KMP算法详解(理论+C语言代码实现)(下)

简介: KMP算法详解(理论+C语言代码实现)(下)

三:next数组特点的证明

四:next数组的优化:nextval数组

五.next数组C语言代码实现

/*
str:代表主串
sub:代表字串
pos:代表从主串的pos位置开始找
*/
void GetNext(char* sub, int* next,int lenSub)
{
  next[0] = -1;
  //子串长度为1,直接返回即可
  if (lenSub == 1)
  {
    return;
  }
  next[1] = 0;
  int i = 2;//当前i下标
  //因为此时还不知道next[i]的值,只知道next[i-1]的值和sub[k]的值
  int k = 0;//前一项的k
  while(i<lenSub)
  {
    //k==-1,此时不能再进行回退了,否则子串会发生越界
    //匹配成功或者k回退到k=-1时,利用next[i-1]=k,推出=>>next[i]=k+1;
    //i和k往后走,继续求解next数组
    if (k==-1 || sub[i - 1] == sub[k])
    {
      next[i] = k + 1;
      i++;
      k++;
    }
    //sub[i-1]!=sub[k],即匹配不成功,k回退
    else
    {
      k = next[k];//k回退
    }
  }
}
int KMP(const char* str,const char* sub, int pos)
{
  //对参数的正确性的判断
  assert(str!=NULL && sub!=NULL);
  int lenStr = strlen(str);
  int lenSub = strlen(sub);
  if (lenStr == 0 || lenSub == 0)
  {
    return -1;
  }
  if (pos < 0 || pos >= lenStr)
  {
    return -1;
  }
  int* next = (int*)malloc(sizeof(int) * lenSub);
  assert(next != NULL);
  GetNext(sub, next, lenSub);
  //开始遍历两个串
  int i = pos;//遍历主串
  int j = 0;//遍历子串
  while (i < lenStr && j < lenSub)
  {
    //对应位置相等,往后走
    //j==-1,此时不能再进行回退了,否则子串会发生越界
    if (j == -1 || str[i] == sub[j])
    {
      i++;
      j++;
    }
    //否则:i不动,j回退
    else
    {
      j = next[j];
    }
  }
  //子串遍历结束,意味着匹配成功
  free(next);
  next = NULL;
  if (j >= lenSub)
  {
    return i - j;
  }
  //主串遍历成功,子串却没有遍历成功,意味着匹配失败
  return -1;
}
//验证
int main()
{
  printf("%d\n", KMP("ababcabcdabcde", "abcd", 0));//5
  printf("%d\n", KMP("ababcabcdabcde", "abcdf", 0));//-1
  printf("%d\n", KMP("ababcabcdabcde", "e", 0));//13
  printf("%d\n", KMP("d", "e", 0));//-1
}
//验证成功

以上就是KMP算法的详解,希望能对大家有所帮助!

相关文章
|
15天前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
41 4
|
13天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
16天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
63 8
|
16天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
55 7
|
25天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
28 3
|
24天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
1月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。
|
1月前
|
存储 搜索推荐 C语言
深入C语言指针,使代码更加灵活(二)
深入C语言指针,使代码更加灵活(二)
|
1月前
|
存储 程序员 编译器
深入C语言指针,使代码更加灵活(一)
深入C语言指针,使代码更加灵活(一)
下一篇
无影云桌面