串的匹配算法--C语言实现
串这种数据结构,使用是比较多的,但是它的一些方法在更高级的语言中,比如Java,Python中封装的比较完整了。在这里,我只写了串中使用最多的匹配算法,即串的定位操作。串的匹配算法常用的两种就是朴素匹配算法和KMP匹配算法。代码亲测,可直接执行。
- #include<stdio.h>
- /*字符串长度*/
- int StringLength(char *L)
- {
- int i = ; //记录位置
- int count = ; //计数器,记录长度
- while(L[i]) //判断当前位置是否为空
- {
- count++; //长度加1
- i++; //计数器加1
- }
- return count; //返回长度
- }
- /*朴素匹配算法*/
- int Index(char *S, char *T) //S为主串,T为子串
- {
- int Slength = StringLength(S); //获得主串S的长度
- int Tlength = StringLength(T); //获得子串T的长度
- int i = ; //记录主串S当前位置
- int j = ; //记录子串T当前位置
- // int count = 0;
- printf("朴素匹配算法中j回溯的值为:");
- while(i < Slength && j < Tlength) //确保两个字符串的当前位置均小于其长度
- {
- // printf("%d ", j);
- // count++;
- if(S[i] == T[j]) //判断主串S当前位置与子串T当前位置的字符是否相等
- {
- i++; //主串S的当前位置加1(后移)
- j++; //子串T的当前位置加1(后移)
- }
- else //如果两字符串的当前位置字符不等
- {
- i = i - j + ; //主串S的当前位置i回溯到j==0时i位置的下一位置
- j = ; //子串T的当前位置j归0
- }
- }
- // printf("\nj共变化了%d次\n", count);
- //循环比较完毕
- if(j == Tlength) //判断位置j的数值是否与子串T的长度相等
- return i - Tlength; //若是,说明搜索成功,返回T在S中出现的首位置
- else
- return -; //若不是,说明T不存在与S中,返回-1
- }
- /*KMP算法*/
- void Get_Next(char *T, int next[])
- {
- int Tlength = StringLength(T); //获得字符串T的长度
- int i = ; //T的后缀位置
- int j = -; //T的前缀位置
- next[] = -; //next数组的首位赋值为-1
- while(i < Tlength) //确保后缀位置小于串长
- {
- if(j == - || T[i] == T[j]) //如果j==-1,说明前缀已经回退到最前方
- { //如果T[i] == T[j],说明当前前缀与后缀相等
- i++; //则后缀位置后移一位
- j++; //前缀位置后移一位
- next[i] = j; //当前后缀位置的next值为j
- }
- else
- j = next[j]; //否则,j回退(还没完全搞懂回退到哪)
- }
- }
- int Index_KMP(char *S, char *T)
- {
- int Slength = StringLength(S); //获得主串S的长度
- int Tlength = StringLength(T); //获得子串T的长度
- int i = ; //记录S的当前位置
- int j = ; //记录T的当前位置
- int next[]; //next数组
- Get_Next(T, next); //调用Get_Next函数,为next赋值
- int count = ;
- // printf("KMP算法中j回溯的值为:");
- while(i < Slength && j < Tlength)
- {
- // printf("%d ", j);
- // count++;
- if(j == - || S[i] == T[j]) //如果j==-1,说明前缀已经回退到最前方
- { //如果S[i] == T[j],说明主串与子串当前位置字符相等
- i++; //S的当前位置后移一位
- j++; //T的当前位置后移一位
- }
- else
- {
- j = next[j]; //否则,j回退(未弄懂回退到哪)
- }
- }
- // printf("\nj共变化了%d次\n", count);
- if(j == Tlength) //比较结束,判断j的值是否与T的长度相等
- return i - Tlength; //若是,返回T在S中出现的开始位置
- else
- return -; //若不是,返回-1
- }
- /*KMP改进版算法*/
- void Get_Next_Val(char *T, int nextVal[])
- {
- int Tlength = StringLength(T); //获得子串T的长度
- int i = ; //记录后缀位置
- int j = -; //记录前缀位置
- nextVal[] = -; //next数组第一位置赋值为-1
- while(i < Tlength)
- {
- if(j == - || T[i] == T[j]) //同上
- {
- i++; //同上
- j++;
- if(T[i] != T[j]) //如果位置后移一位后的值不相等
- nextVal[i] = j; //nextVal等于j
- else //如果相等
- nextVal[i] = nextVal[j]; //当前后缀位置的nextVal值等于j位置的nextVal的值
- }
- else
- j = nextVal[j]; //同上
- }
- }
- int Index_KMP_Val(char *S, char *T)
- {
- int Slength = StringLength(S); //获得主串S的长度
- int Tlength = StringLength(T); //获得子串T的长度
- int i = ; //记录S的当前位置
- int j = ; //记录T的当前位置
- int next[]; //next数组
- Get_Next_Val(T, next); //调用Get_Next函数,为next赋值
- int count = ;
- printf("KMP_Val算法中j回溯的值为:");
- while(i < Slength && j < Tlength)
- {
- printf("%d ", j);
- count++;
- if(j == - || S[i] == T[j]) //如果j==-1,说明前缀已经回退到最前方
- { //如果S[i] == T[j],说明主串与子串当前位置字符相等
- i++; //S的当前位置后移一位
- j++; //T的当前位置后移一位
- }
- else
- {
- j = next[j]; //否则,j回退(未弄懂回退到哪)
- }
- }
- printf("\nj共变化了%d次\n", count);
- if(j == Tlength) //比较结束,判断j的值是否与T的长度相等
- return i - Tlength; //若是,返回T在S中出现的开始位置
- else
- return -; //若不是,返回-1
- }
- void main()
- {
- char *S = "aaaaaaaaaaaaaaaaaaaaabcde";
- char *T = "aaaaaaaaaaaaaaaaaaaaaaaax";
- int pos;
- pos = Index(S, T);
- if(pos != -)
- printf("朴素匹配算法:子串T在主串S的下标为%d的位置上开始出现\n", pos);
- else
- printf("朴素匹配算法:子串T不存在与主串S中\n");
- printf("---------------------------------------------------------------------\n");
- int pos_KMP;
- pos_KMP = Index_KMP(S, T);
- if(pos_KMP != -)
- printf("KMP匹配算法:子串T在主串S的下标为%d的位置上开始出现\n", pos_KMP);
- else
- printf("KMP匹配算法:子串T不存在与主串S中\n");
- printf("---------------------------------------------------------------------\n");
- int pos_KMP_val;
- pos_KMP_val = Index_KMP_Val(S, T);
- if(pos_KMP_val != -)
- printf("KMP_Val匹配算法:子串T在主串S的下标为%d的位置上开始出现\n", pos_KMP_val);
- else
- printf("KMP_Val匹配算法:子串T不存在与主串S中\n");
- }
串的匹配算法--C语言实现的更多相关文章
- BF算法(串模式匹配算法)
主串和子串 主串与子串:如果串 A(如 "shujujiegou")中包含有串 B(如 "ju"),则称串 A 为主串,串 B 为子串.主串与子串之间的关系可简 ...
- SHA算法:签名串SHA算法Java语言参考(SHAHelper.java)
SHAHelper.java package com.util; /** * @author wangxiangyu * @date:2017年10月16日 上午9:00:47 * 类说明:SHA签名 ...
- UTF-8, Unicode, GB2312格式串转换之C语言版
原住址:http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html /* author: wu.j ...
- 7、UTF-8, Unicode, GB2312格式串转换之C语言版
(申明:此文章属于原创,若转载请表明作者和原处链接 ) /* author: wu.jian (吴剑) English name: Sword ...
- 括号匹配算法 C语言实现
#include <stdio.h> #include <malloc.h> //malloc,realloc #include <math.h> //含有over ...
- 4-4-串的KMP匹配算法-串-第4章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第4章 串 - KMP匹配算法 ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码 ...
- 串、KMP模式匹配算法
串是由0个或者多个字符组成的有限序列,又名叫字符串. 串的比较: 串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号. 计算机中常用的ASCII编码,由8位二进制 ...
- 数据结构(c语言版)代码
第1章 绪论 文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论 概述 第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语.对于这些概念术语 ...
- KOTLIN开发语言文档(官方文档) -- 2.基本概念
网页链接:https://kotlinlang.org/docs/reference/basic-types.html 2. 基本概念 2.1. 基本类型 从可以在任何变量处理调用成员函数和属性 ...
随机推荐
- if __name__ == "__main__" 的作用
作用:当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行. 例子: # file one.py def func(): print("func() in one.py& ...
- 《吊打面试官》系列-Redis终章_凛冬将至、FPX_新王登基
你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难.作为一个在互联 ...
- 只需十四步:从零开始掌握Python机器学习(附资源)
转载:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源.你现在也在考虑从 Python 入门机器学习吗?本教程或许 ...
- dhcpv6+radvd服务器搭建
1.isc-dhcp-server install sudo apt update sudo apt-get install isc-dhcp-server 2.设置dhcp 创建/etc/dhcp/ ...
- 2019年10月11号 王庆超 linux
1.计算机操作系统简介 (1)掌握操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统 程序,它位于硬件和应用程序之间. (2)掌握操作系统的内核的定义:操作系统的内核是一个管 ...
- PHP获取PHP执行的时间
php获取PHP执行的时间 <pre> //程序运行时间 $starttime = explode(' ',microtime()); //代码区域 //程序运行时间 $endtime = ...
- Python面向对象 | 类的成员
一. 细分类的组成成员 之前咱们讲过类大致分两块区域,静态字段部分和方法部分. 每个区域详细划分又可以分为: class A: company = '阿里巴巴' # 静态变量(静态字段) __tel ...
- 淘宝小练习#css
* { margin: 0; padding: 0; } a { text-decoration: none; } .box { background: #f4f4f4; } /* 头部样式STAR ...
- 配置SElinux环境,将SELinux设置为enforcing
SELinux是 美国国家安全局 (NSA) 对于 强制访问控制的实现 =>可以使root受限的权限 关闭SELinux=>修改配置文件,永久生效; sed -i 's/SELINUX=e ...
- PHP 修改数组中的值
PHP 修改数组中的值 ①.二维数组可以通过 for($i = 0; $i < count(Array()); ++ $i) 这种形式修改 实例代码: // 修改 二维数组中的 name为 Ge ...