C语言实现KMP算法与扩展字符串匹配练习

周予安
周予安
发布时间:2026-10-13| 5人浏览过
原创

KMP算法是处理字符串匹配问题的高效工具,通过预处理模式串获取部分匹配表(Next数组),避免回溯主串指针。本文将展示该算法在C语言中的标准实现,并进一步探讨解决包含中括号通配符条件的扩展匹配问题。

核心原理:构建Next数组

KMP算法的关键在于计算模式串的 next 数组。该数组记录了当匹配失败时,模式串指针应回退的最长公共前后缀长度位置。以下是获取该值的C语言实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int get_nextval(char *pattern, int next[])
{
  //get the next value of the pattern 
  int i = 0, j = -1;
  next[0] = -1;
  int patlen = strlen(pattern);
  while ( i < patlen - 1){
    if ( j == -1 || pattern[i] == pattern[j]){
      ++i;
      ++j;
      if (pattern[i] != pattern[j])
        next[i] = j;
      else
        next[i] = next[j];
    }
    else
      j = next[j];
    }

  return(0);
}

完整流程:KMP匹配索引查询

在获得 next 数组后,即可通过一次遍历查找目标串中模式串首次出现的位置。该方法利用预处理的跳转信息跳过无效比较,显著提升性能。

int kmpindex(char *target, char *pattern, int pos)
{
  int tari = pos, pati = 0; 
  int tarlen = strlen(target), patlen = strlen(pattern);
  int *next = (int *)malloc(patlen * sizeof(int));
  get_nextval(pattern, next);
  while ( tari < tarlen && pati < patlen ){
    if (pati == -1 ||target[tari] == pattern[pati]){
      ++tari;
      ++pati;
      }else{
        pati = next[pati];
      }
  }  
if(next != NULL) free(next);
next = NULL;
if (pati == patlen)
  return tari - pati;
else
  return -1;
}


int main()
{
  char target[50], pattern[50];
  printf("imput the target:\n" );
  scanf("%s",target);
  printf("imput the pattern:\n" );
  scanf("%s",pattern);
  int ans = kmpindex(target,pattern,0);
  if (ans == -1)
    printf("error\n");
  else
    printf("index:%d\n",ans);
  return 0;
}

进阶挑战:支持中括号通配符的匹配

在某些特定场景中,字符串可能包含用中括号表示的模式匹配规则。例如 “aa[123]bb” 代表 “aa1bb”、“aa2bb” 或 “aa3bb” 均可视为有效匹配。下面针对此类需求提供一套C语言的完整解决方案:

题目逻辑要求读入多组数据,每组包含 N 个待查字符串及一个带有特殊格式的主字符串。系统需输出所有匹配到的行号及对应的原始字符串(匹配过程不区分大小写)。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
  
#define MAX 1001 
#define LEN 101 
  
struct str 
{ 
  char name[101]; 
}; 
  
int main() 
{ 
  struct str strs[MAX]; 
  struct str t[LEN]; 
  int i, n, len, j, k, left, right, count, flag; 
  char text[LEN], newtext[LEN]; 
  
  while (scanf("%d", &n) != EOF) { 
    // 接收数据 
    getchar(); 
    for (i = 0; i < n; i ++) { 
      scanf("%s", strs[i].name); 
    } 
  
    // 接收文本串 
    getchar(); 
    gets(text); 
    len = strlen(text); 
  
    for (i = left = right = 0; i < len; i ++) { 
      if (text[i] == '[') { 
        left = i; 
      } else if (text[i] == ']') { 
        right = i; 
        break; 
      } 
    } 
    count = right - left - 1; 
  
    if (count <= 0) {  // 没有正则匹配 
      for (i = j = 0; i < len; i ++) { 
        if (text[i] != '[' && text[i] != ']') { 
          newtext[j ++] = text[i]; 
        } 
      } 
      newtext[j] = '\0'; 
      for (i = 0; i < n; i ++) { 
        if (strcasecmp(strs[i].name, newtext) == 0) { 
          printf("%d %s\n", i + 1, strs[i].name); 
        } 
      } 
    }else { // 需要正则匹配 
      for (j = 1, k = 0; j <= count; j ++, k ++) { // 构建文本数组 
        memset(t[k].name, '\0', sizeof(t[k].name)); 
        for (i = 0; i < left; i ++) { 
          t[k].name[i] = text[i]; 
        } 
        t[k].name[i] = text[left + j]; 
        strcat(t[k].name, text + right + 1);   
      }   
      
      // 正则匹配  
      for (i = 0; i < n; i ++) { 
        for (j = flag = 0; j < count; j ++) { 
          if (strcasecmp(strs[i].name, t[j].name) == 0) { 
            flag = 1; 
            break; 
          } 
        } 
        if (flag) { 
          printf("%d %s\n", i + 1, strs[i].name); 
        } 
      } 
    } 
  
  } 
  
  return 0; 
}

上述代码首先定位中括号范围以确定生成多少种候选分支。若无特殊字符则直接执行不区分大小写的字符串比对;若有,则在循环中动态构造多个变体逐一验证。此方法适用于中小规模数据的精确模式搜索任务。

以上就是使用C语言解决字符串匹配问题的详细内容,更多关于KMP算法在C语言中应用及扩展匹配技巧的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。