串这种数据结构,使用是比较多的,但是它的一些方法在更高级的语言中,比如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语言实现的更多相关文章

  1. BF算法(串模式匹配算法)

    主串和子串 主串与子串:如果串 A(如 "shujujiegou")中包含有串 B(如 "ju"),则称串 A 为主串,串 B 为子串.主串与子串之间的关系可简 ...

  2. SHA算法:签名串SHA算法Java语言参考(SHAHelper.java)

    SHAHelper.java package com.util; /** * @author wangxiangyu * @date:2017年10月16日 上午9:00:47 * 类说明:SHA签名 ...

  3. UTF-8, Unicode, GB2312格式串转换之C语言版

    原住址:http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html           /*      author:   wu.j ...

  4. 7、UTF-8, Unicode, GB2312格式串转换之C语言版

    (申明:此文章属于原创,若转载请表明作者和原处链接 )            /*      author:   wu.jian    (吴剑)      English name: Sword    ...

  5. 括号匹配算法 C语言实现

    #include <stdio.h> #include <malloc.h> //malloc,realloc #include <math.h> //含有over ...

  6. 4-4-串的KMP匹配算法-串-第4章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第4章  串 - KMP匹配算法 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码 ...

  7. 串、KMP模式匹配算法

    串是由0个或者多个字符组成的有限序列,又名叫字符串. 串的比较: 串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号. 计算机中常用的ASCII编码,由8位二进制 ...

  8. 数据结构(c语言版)代码

    第1章  绪论       文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论  概述        第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语.对于这些概念术语 ...

  9. KOTLIN开发语言文档(官方文档) -- 2.基本概念

    网页链接:https://kotlinlang.org/docs/reference/basic-types.html 2.   基本概念 2.1.  基本类型 从可以在任何变量处理调用成员函数和属性 ...

随机推荐

  1. Android 常见内存泄露 & 解决方案

    前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...

  2. CSPS模拟 69

    $C_n^0=1$ $C_n^0=1$ $C_n^0=1$ 我怎么又双叒叕犯这种错误了啊 (咳檀) T1 WA0,大神题,不会做! T2 就是要找一个最长区间,满足左端点是区间最小值,右端点是区间最大 ...

  3. CSPS模拟 65

    cbx又A两题%%% T1比较水,只需要想到lcm以内的数都只能被唯一凑出就可以. T2比较shi,毕竟std复杂度都不正确的题是不能称之为完整的题的. 那么再感受一下T3满满的恶意 起点已经固定了, ...

  4. linux写系统服务的方法

    linux写系统服务的方法 2.1 首先编写demo程序:hello.c<pre>#include <stdio.h> # chkconfig: 2345 10 90 main ...

  5. 查看redis占用内存大小的方法

    查看redis占用内存大小的方法 <pre>redis-cli auth 密码info</pre><pre># Memory used_memory:1349009 ...

  6. day1-习题

    # 1.使用while循环输入 1 2 3 4 5 6 8 9 10 count = 1 while count<11 : #使用while语句循环输入123...10 if count == ...

  7. 前端与算法 leetcode 7. 整数反转

    目录 # 前端与算法 leetcode 7. 整数反转 题目描述 概要 提示 解析 解法 算法 传入测试用例的运行结果 执行结果 GitHub仓库 # 前端与算法 leetcode 7. 整数反转 题 ...

  8. 《JAVA 程序员面试宝典(第四版)》之JAVA程序设计基础概念(1)类型转换

      问题主题:类型转换   书页号码:37页 题目: 讨论点:答案不是D,应该是B 理由:看下面在编译器输入的结果 知识扩展:装箱与拆箱, == 与 equals 区别 之前也老是听说什么装箱.拆箱之 ...

  9. 2018.3.7java 学习第二天

    java 学习的第二天,首先我们要学习的是声明变量,在程序中,我们必须先声明变量,然后才可以去使用之,那么变量究竟是什么呢? 在很多课本上,有很多的定义诸如:“变量来源于数学,是计算机语言中能储存计算 ...

  10. 2C 还是 2B,跟找工作有什么关系?

    通常,我们会把公司的业务类型分成以下几种: 2C,to Customer,指面向个人客户的业务,即将公司的产品或服务销售给个人,通常做出购买决策的个人也是使用产品或服务的用户.举例说明,像 BAT 发 ...