数据结构_串_串的模式匹配_KMP/BF_数据结构串的模式匹配指针回溯-程序员宅基地

技术标签: # 数据结构    KMP算法  数据结构  串的模式匹配  KMP  

        串是由零个或者多个字符组成的有序序列,又名叫字符串。在串中涉及到一下几个概念:串的长度、空串、子串、以及串的比较和串的模式匹配。

串的比较:

       计算机中使用的是标准的ASCII编码,是由7位二进制数表示一个字符,总共可表示2^7=128个字符,后来由于特殊符号的出现,扩展成8位二进制数表示一个字符,共表示2^8=256个字符。再后来由于世界上的语种非常的多,就产生了Unicode编码,用16位二进制数表示一个字符,总共可表示2^16=6.5万多个字符。当然,Unicode编码的前256个字符和ASCII码完全相同。而字符串的比较则是逐位按照ASCII码的大小进行比较,那么软件中查取相应单词的过程就是这样产生的。

串的模式匹配:

普通的模式匹配算法:

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
using namespace std;

int BF(const char *des, const char *src, int pos)//返回下标
{
    if (des == nullptr || src == nullptr)
    {
        return -1;
    }
    int lend = strlen(des);
    int lens = strlen(src);
    if (pos < 0 || p >= lend)
    {
        return -1;
    }
    //while循环进行查找
    int i = pos;
    int j = 0;
    while (i < lend && j < lens)
    {
        if (des[i] == src[j])
        {
            ++i;
            ++j;
        }
        else
        {
            i = i-j+1;
            j = 0;
        }
    }
    if (j >= lens)
    {
        return i-j;
    }
    return -1;
}

int main()
{
    
    
    return 0;
}
     
     
    
    
   
   
KMP算法模式匹配: 对于普通的模式匹配算法而言,当des = "abcdefgoogle"和src = "google"的时候,时间复 杂度
                 为O(n+m);而当des = "000000000000000001"和src = "00001"的时候,时间复杂度则变 成了O((n-
                 m+1)*m),时间复杂度很高。而这其中产生时间消耗的主要是重复的比较造成的。 我们假设i为des
                 的下标,j为src的下标,KMP算法的核心就是i不回溯(不回退),而j根据子串中是否有重复的问题
                 进行选择性回退,j的回退与主串无任何关系。那么j到底回退到什么位置合适,则由next数组和
                 nextval数组确定。
   【next数组】

       next数组的计算相当的简单,不同的教材上方法可能有些许差异,即:next[0] = 0 或者 next[0] = -1;

       例:char arr[] = "a  b  a  b  a  a  a  b  a";

               int next[] = {0, 1, 1, 2, 3, 4, 2, 2, 3};

      【nextval数组】

      nextval数组是next数组的一个改进版本。需要注意的是当next[0] = 0时,next数组的值是表示的第几个元素,当

      next[0] = -1的时候,表示的是当前下标为next数组值得元素。

       例:      char arr[] = "a  b  a  b  a  a  a  b  a";

        int nextval[] = {0, 1, 0, 1, 0, 4, 2, 1, 0};


KMP算法next版本实现:

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         using namespace std; void findNext(const char *src, int *next) { //入口检查 if (src == nullptr || next == nullptr) { return ; } int i = 1;//表示当前要求next数组元素的下标 int j = 0;//表示next的数组元素 next[0] = -1; next[1] = 0; int lens = strlen(src); while (i < lens) { //此处的j == 0保证不会出现 j==-1的情况 if (j==0 || src[i] == src[j]) { ++i; ++j; next[i] = j; } else { j = next[j]; } } } int KMP(const char *des, const char *src, int pos) { if (des == nullptr || src == nullptr) { return -1; } int lend = strlen(des); int lens = strlen(src); int i = pos; int j = 0; //动态创建next数组 int *next = new int[100]; findNext(src, next); while (i < lend && j < lens) { if (j==-1 || des[i] == src[j]) { ++i; ++j; } else { j = next[j]; } } delete []next; if (j > lens) { return i-lens; } else { return -1; } } int main() { char *des = "abcdefgoogle"; //char *src = "ef"; //char *src = "le"; //char *src = ""; //char *src = nullptr; char *src = " "; int pos = KMP(des, src, 2); cout< 
        
          < 
          
         
       
      
      
     
     
    
    
   
   

KMP算法nextval版本实现:

#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        

void findNextVal(const char *src, int *nextval)
{
    if (src == nullptr || nextval == nullptr)
    {
        return ;
    }
    int lens = strlen(src);
    if (lens == 0)
    {
        return ;
    }
    nextval[0] = -1;
    nextval[1] = 0;
    int i = 1;
    int j = 0;
    while (i < lens)
    {
        if (j == 0 || src[i] == src[j])
        {
            ++i;
            ++j;
            if (src[i] != src[j])
            {
                nextval[i] = j;
            }
            else
            {
                nextval[i] = nextval[j];
            }
        }
        else
        {
            j = nextval[j];
        }
    }
}

int KMP(const char *des, const char *src, int pos)
{
    if (des == nullptr || src == nullptr)
    {
        return -1;
    }
    int lend = strlen(des);
    int lens = strlen(src);
    if (pos < 0 || pos >= lend)
    {
        return -1;
    }
    int i = pos;
    int j = 0;
    int nextval[100];
    findNextVal(src, nextval);
    
    while (i < lend && j < lens)
    {
        if (j == 0 || des[i] == src[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j = nextval[j];
        }
    }
    if (j >= lens)
    {
        return i-j;
    }
    else
    {
        return -1;
    }
}

int main()
{
    char *des = "abcdefgoogle";
	//char *src = "ef";
	//char *src = "le";
	//char *src = "";
	//char *src = nullptr;
	char *src = " ";
	int pos = KMP(des, src, 2);
	cout<
        
        
          < 
          
        
       
       
      
      
     
     
    
    




版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/admin_maxin/article/details/53967937

智能推荐

bookmark20160330_u8ur.lat-程序员宅基地

文章浏览阅读4.6w次。It will be read and overwritten. DO NOT EDIT! -->BookmarksBookmarks 书签栏 百度一下,你就知道 20160311 redis - 必应 REDIS 3.0.7 下载 _u8ur.lat

使用关系抽取模型SpanBERT遇到的问题_spanbert做关系抽取-程序员宅基地

文章浏览阅读772次。在google colab安装apex运行以下程序,安装apex !git clone https://github.com/NVIDIA/apex cd apex !pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" 运行程序后,仍然出现问题ImportError: cannot import name 'FP16_Optimizer'ImportErro.._spanbert做关系抽取

路径跟踪—Matlab LQR库函数无法代码生成,那就手写一个_手写lqr函数-程序员宅基地

文章浏览阅读2.5k次,点赞9次,收藏38次。Matlab环境下无法对lqr,dlqr,care,dare函数进行代码生成,如果您想用在Simulink环境下使用该函数,会告诉您无法进行代码生成,这时您加上外部函数是可以在Simulink环境下使用的。// An highlighted blockcoder.extrinsic(function)但是如果您想将在线lqr函数部署到您的实际控制器中,比如车辆路径跟踪dlqr算法的时候,您又不想事先求解好反馈增益K,或者您需要时变的Q和R矩阵,那么就无法将lqr函数代码生成部署到快速控制原型或者工控_手写lqr函数

redhat 5.4 下 Oracle RAC 报 raw 设备大小 错误_raw超出分配大小-程序员宅基地

文章浏览阅读9.3k次。 在Redhat 5.4 上安装oracle 10g的RAC。在安装Clusterware 的时候,出现错误: Raw 设备的大小肯定是没有问题,因为我分配的raw 是200M一个,但是它只识别了16M。 配置文件就那么几步,看了几遍都没有发现问题。google 百度也没有什么有价值的信息。 磁盘分区大小:[root@rac1 raw_raw超出分配大小

精读论文:Multi-Task Learning as Multi-Objective Optimization(附翻译)-程序员宅基地

文章浏览阅读7.3k次,点赞26次,收藏62次。Multi-Task Learning as Multi-Objective Optimization二、翻译0. 摘要abstract:在多任务学习中,多个任务共同解决,它们之间共享归纳偏差。多任务学习本质上是一个多目标问题,因为不同的任务可能会发生冲突,因此需要进行权衡。常见的折衷方案是优化代理目标(proxy objective),以最小化每个任务损失的加权线性组合。但是,这种解决方法仅在任务不竞争时才有效,这种情况很少发生。在本文中,我们明确地将多任务学习视为多目标优化,其总体目标是找到帕累_multi-task learning as multi-objective optimization

基于php的新闻发布系统免费下载,基于php的新闻发布系统的设计与实现-程序员宅基地

文章浏览阅读426次。基于php的新闻发布系统的设计与实现 四个模块基于PHP的新闻发布系统设计与实现作者 刘兴荣 指导教师 程涛【摘要】伴随着网络的出现,网页逐渐融入人们的生活。快速及时的新闻浏览,五彩缤纷的网上信息,使网络与人们生活息息相关。足不出户便可知天下大事,网上新闻发布系统可使系统管理员方便、快速、简洁的发布新闻,普通用户能够浏览新闻,将需要经常变动或添加的内容进行分类管理,最后系统化、标准化的发布到..._新闻发布系统的设计与实现 php

随便推点

R语言 X轴为日期时 使用scale_x_date-程序员宅基地

文章浏览阅读9.7k次,点赞3次,收藏13次。scale_x_date(name = ..., breaks = ..., labels = ..., limits = ...)scale_x_date(name="x轴名称",breaks=date_breaks("1 month"),labels=date_format("%Y-%m"),limits=as.Date(c("2014-01-01","2018-01-01"))..._scale_x_date

ajax跨域加载html页面,关于javascript:如何进行简单的跨域ajax调用以返回html页面...-程序员宅基地

文章浏览阅读317次。提交 button>form>(函数($){函数processForm(e){$ .ajax({网址:" myserver.com:8080/myApp/user-login.jsp",crossDomain:是的,dataType:" html",类型:" post",contentType:" application / x-www-form-urlencoded",数据:$(th..._js 跨域请求html返回html页面

Python之selenium库基础_selenium 清华-程序员宅基地

文章浏览阅读1.5k次,点赞3次,收藏19次。Python之selenium库基础_selenium 清华

Android ViewPager+Fragment切换显示不出的问题_android开发中,切换多语言,viewpager里面的fragment没有切换-程序员宅基地

文章浏览阅读8.4k次,点赞10次,收藏11次。今天遇到一个问题,之前也有遇到过,但是没有做笔记,时间一久也就忘了,这次项目又遇到了这个问题,却没有想起之前的解决方法,所以把他写到博客记录一下,以便不再犯同样的错误,android基础学得不是很扎实,问题很简单,不要见怪啊。好了,废话少说,下面说正题。我们在使用ViewPager+Fragment做切换的时候,可能我们在编写数据适配器的时候会这样写 class MyFragmentPagerAd_android开发中,切换多语言,viewpager里面的fragment没有切换

VS报错 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义 链接报错: 错误 33 error LNK2005: _DllMai_error lnk2005: _dllmain@12 已经在 msvcrtd.lib(dll_dll-程序员宅基地

文章浏览阅读593次。VS报错 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义链接报错:错误 33 error LNK2005: _DllMain@12 已经在 MSVCRTD.lib(dllmain.obj) 中定义 E:\客户问题\w_王鹏\EventLibTest_TibrvAlternative_Mult_error lnk2005: _dllmain@12 已经在 msvcrtd.lib(dll_dllmain_stub.obj) 中定义

openpyxl报错:OSError: File contains no valid workbook part-程序员宅基地

文章浏览阅读7.9k次,点赞6次,收藏5次。raise IOError("File contains no valid workbook part")OSError: File contains no valid workbook part原因:用openpyxl 模块读取了xls格式的excel,或者读取的是xls文件通过改变后缀变成xlsx格式的文件解决:重新创建xlsx的文件..._file contains no valid workbook part