第五章 字符串专题 ---------------- 字符串匹配(三)----后缀数组算法

字符串匹配:字符串hash,后缀数组,高度数组,AC自动机,KMP 一、字符串hash二、后缀数组三、高度数组四、KMP五、AC自动机 一、字符串hash 字符串hash+二分入门题 寻找字符串s中字符串t出现的位置或次数的问题属于字符串匹配问题。我们在接下来的讨论中假设s的长度为n,T的长度为m。 最朴素的想法是,枚举所有起始位置,再直接检查是否匹配,复杂度为O(mn)O(mn)O(mn)的算法。还有几个更为高效的算法。而在此我们只介绍实现起来较为容易,... 阅读详情

一、什么是后缀数组:

  字符串后缀Suffix 指的是从字符串的某个位置开始到其末尾的字符串子串。后缀数组 Suffix Array(sa) 指的是将某个字符串的所有后缀按字典序排序之后得到的数组,不过数组中不直接保存所有的后缀子串,只要记录后缀的起始下标就好了。

  比如下面在下面这张图中,sa[8] = 7,表示在字典序中排第9的是起始下标为7的后缀子串,这里还有一个比较重要的数组rank,rank[i] : sa[i]在所有后缀中的排名 ,比如rk[5]=0,表示后缀下标为5的子串在后缀数组中排第0个; rank数组与sa数组互为逆运算,rk[sa[i]]=i。

  现在假如我们已经求出来了后缀数组,然后直接对已经排好序的后缀数组进行二分查找,这样就能匹配成功了,下面贴出代码:

import java.util.Arrays;

public class SuffixArrayTest {
    public static void main(String[] args) {
        match();  // 得到结果是5
    }
    
    static void match(){
        String s = "ABABABABB";
        String p = "BABB";
        Suff[] sa = getSa(s); // 后缀数组
        int l = 0;
        int r = s.length()-1;
        // 二分查找 ,nlog(m)
        while(r>=l){
            int mid = l + ((r-l)>>1);
            // 居中的后缀
            Suff midSuff = sa[mid];
            String suffStr = midSuff.str;
            int compareRes;
            // 将后缀和模式串比较,O(n);
            if (suffStr.length()>=p.length()) {
                compareRes = suffStr.substring(0, p.length()).compareTo(p);
            }else {
                compareRes = suffStr.compareTo(p);
            }
            // 相等了 输出后缀的起始位置
            if(compareRes == 0){
                System.out.println(midSuff.index);
                break;
            }else if (compareRes<0) {
                l = mid + 1;
            }else {
                r = mid - 1;
            }
        }
    }
    /**
     * 直接对所有后缀排序,因为字符串的比较消耗O(N),所以整体为N²log(N)
     * @param src
     * @return
     */
    public static Suff[] getSa(String src){
        int strLength = src.length();
        // sa 即SuffixArray,后缀数组  
        // sa 是排名到下标的映射,即sa[i]=k说明排名为i的后缀是从k开始的
        Suff[] suffixArray = new Suff[strLength];
        for (int i = 0; i < strLength; i++) {
            String suffI = src.substring(i);   //截取后缀
            suffixArray[i] = new Suff(suffI, i);
        }
        Arrays.sort(suffixArray);   //依据Suff的比较规则进行排序
        return suffixArray;
    }
    
    static class Suff implements Comparable<Suff>{

        String str;  //后缀内容
        int index;   //后缀的起始下标
        
        public Suff(String str, int index) {
            super();
            this.str = str;
            this.index = index;
        }

        @Override
        public int compareTo(Suff o2) {
            return this.str.compareTo(o2.str);
        }
        @Override
        public String toString() {
            return "Suff{"+"str='"+str+"\'"+",index="+index+"}";
        }
        
    }
}

 二、倍增法:

       上面求后缀数组的方式时间复杂度为n²log(n),一般来说,时间复杂度只要达到了n平方级别都要想办法降低,于是就有一种叫做倍增法的方法来求后缀数组,基本思想就是:

   1、先将每个字符排序 得到sa,rank数组,

   2、然后给每个字符增添一个字符,这样就变成了两个字符,最后一个字符无法增添字符,就需要处理好边界问题。然后就是排序,排序规则的话就需要自定义规则

   3、然后再在两个字符的基础上添加两个字符,就变成四个字符,然后再在上一次排序的规则上进一步排序。然后八个字符......

  最主要的降低时间复杂度的方式就是根据每一步更新后的rank数组来进行下一步的排序,这样前面已经排好序的就不用比较了。嗯。。。具体的倍增法的思想的话只有自己在具体应用代码的时候慢慢琢磨,通过不断地调试慢慢理解。这里的代码直接都是封装好了方法直接调用即可。下面贴出代码:

import java.util.Arrays;

public class SuffixArray {
    public static void main(String[] args) {
        match();  // 得到结果是5
    }
    
    static void match(){
        String s = "ABABABABB";
        String p = "BABB";
//        SuffixArray.Suff[] sa = SuffixArray.getSa(s); // 后缀数组
        Suff[] sa = getSa2(s); // 后缀数组
        int l = 0;
        int r = s.length()-1;
        // 二分查找 ,nlog(m)
        while(r>=l){
            int mid = l + ((r-l)>>1);
            // 居中的后缀
            Suff midSuff = sa[mid];
//            String suffStr = midSuff.str;
            String suffStr = s.substring(midSuff.index);
            int compareRes;
            // 将后缀和模式串比较,O(n);
            if (suffStr.length()>=p.length()) {
                compareRes = suffStr.substring(0, p.length()).compareTo(p);
            }else {
                compareRes = suffStr.compareTo(p);
            }
            // 相等了 输出后缀的起始位置
            if(compareRes == 0){
                System.out.println(midSuff.index);
                break;
            }else if (compareRes<0) {
                l = mid + 1;
            }else {
                r = mid - 1;
            }
        }
    }
    
    
    /**
     * nlg²n 构建后缀数组
     * 
     * @param src
     * @return
     */
    public static Suff[] getSa2(String src) {
        int n = src.length();
        Suff[] sa = new Suff[n];
        for (int i = 0; i < n; i++) {
            sa[i] = new Suff(src.charAt(i), i, src);// 存单个字符,接下来排序
        }
        Arrays.sort(sa);

        /** rk是下标到排名的映射 */
        int[] rk = new int[n];// suffix array
        rk[sa[0].index] = 1;
        for (int i = 1; i < n; i++) {
            rk[sa[i].index] = rk[sa[i - 1].index];
            if (sa[i].c != sa[i - 1].c)
                rk[sa[i].index]++;
        }
        // 倍增法
        for (int k = 2; rk[sa[n - 1].index] < n; k *= 2) {

            final int kk = k;
            Arrays.sort(sa, (o1, o2) -> {
                // 不是基于字符串比较,而是利用之前的rank
                int i = o1.index;
                int j = o2.index;
                if (rk[i] == rk[j]) {// 如果第一关键字相同
                    if (i + kk / 2 >= n || j + kk / 2 >= n)
                        return -(i - j);// 如果某个后缀不具有第二关键字,那肯定较小,索引靠后的更小
                    return rk[i + kk / 2] - rk[j + kk / 2];

                } else {
                    return rk[i] - rk[j];
                }
            });
            /*---排序 end---*/
            // 更新rank
            rk[sa[0].index] = 1;
            for (int i = 1; i < n; i++) {
                int i1 = sa[i].index;
                int i2 = sa[i - 1].index;
                rk[i1] = rk[i2];
                try {
                    if (!src.substring(i1, i1 + kk).equals(src.substring(i2, i2 + kk)))
                        rk[i1]++;
                } catch (Exception e) {
                    rk[i1]++;
                }
            }
        }

        return sa;
    }
    
    public static class Suff implements Comparable<Suff> {
        public char c;// 后缀内容
        private String src;
        public int index;// 后缀的起始下标

        public Suff(char c, int index, String src) {
            this.c = c;
            this.index = index;
            this.src = src;
        }

        @Override
        public int compareTo(Suff o2) {
            return this.c - o2.c;
        }

        @Override
        public String toString() {
            return "Suff{" + "char='" + src.substring(index) + '\'' + ", index=" + index + '}';
        }
    }
}

三、高度数组

  高度数组是后缀数组伴生的一个东西。假设有字符串"ABABABB",那它的所有后缀为,以及后缀数组为:

 

       高度数组为所有后缀排好序之后的相邻两个后缀之间的最大公共前缀(LCP),比如height[1],看下标为1的后缀ABABB与上一个下标0的后缀ABABABB,最大公共前缀为ABAB,四个,那么height[1] = 4其余的也是一样,那么可以得到高度数组为height[] = {0,4,2,0,1,3,1}

  高度数组有一个重要规律就是:上一个下标i假如有k个公共前缀,并且k>0,那么下一个下标至少有一个k-1个公共前缀,那么前k个字符是不用比较的。

static int[] getHeight(String src,Suff[] sa){
        // Suff[] sa = getSa2(src);
        int strLength = src.length();
        int []rk = new int[strLength];
        // 因为原来的sa数组是按照字符串相同排名相同,现在调整排名为不重复的排名,重新排名后得到数组rk。
        // 将rank表示为不重复的排名即0~n-1
        for (int i = 0; i < strLength; i++) {
            rk[sa[i].index] = i;
        }
        int []height = new int[strLength];
        // (存在的规律是上一个下标i假如有k个公共前缀,并且k>0,
        //  那么下一个下标至少有一个k-1个公共前缀,那么前k个字符是不用比较的)
        // 利用这一点就可以O(n)求出高度数组
        int k = 0;
        for(int i=0;i<strLength;i++){
            int rk_i = rk[i];  // i后缀的排名
            if (rk_i==0) {
                height[0] = 0;
                continue;
            }
            int rk_i_1 = rk_i - 1;
            int j = sa[rk_i_1].index;// j是i串字典序靠前的串的下标
            if (k > 0)
                k--;

            for (; j + k < strLength && i + k < strLength; k++) {
                if (src.charAt(j + k) != src.charAt(i + k))
                    break;
            }
            height[rk_i] = k;
            
        }
        return height;
    }

 

《大话数据结构》第五章 串 文章目录第五章 串串的存储结构朴素的模式匹配算法KMP模式匹配算法KMP模式算法改进JAVA实现KMP相关 第五章 串 定义:串是由零个或多个字符串组成的有限序列,又叫字符串。 子串和主串:串中任意个数的连续字符组成的子序列称为该串的子串,相应的包含子串的串称为主串。 字串在主串中的位置就是子串的第一个字符在主串中的序号。 串的比较:串的比较是通过串的字符之间的编码来进行的。 串的抽象数据类型: 串的存储结构 串的顺序存储结构:用一组地址连续的存储单元来存储串中的字符序列。 可能会在第一个或最后一个元 阅读详情

相关推荐

雷达信号处理——恒虚警检测(CFAR)

上图展示的是同时在距离维和多普勒维进行恒虚警检测的原理,如果只是在距离维或多普勒维做CFAR,检测单元的左右两侧均有设定好数量的保护单元和参考单元。不同的CFAR检测器适用于不同的场景,CA-CFAR算法适用于均匀环境中的单目标或彼此相距较远的多目标环境,在邻近多目标环境会发生目标的遮蔽效应,在杂波边缘会发生杂波边缘效应。从图中也可以看到,根据阈值的选择不同,有不同的检测器,其中CA-CFAR是取的参考单元的均值,SO-CFAR取的是参考单元的最小值,而GO-CFAR是取的参考单元的最大值。

诚朴勇毅 3万+

后缀数组(Suffix Array)在字符串匹配中的应用

前言 首先抛出一个问题: 给定300w字符串A, 之后给定80w字符串B, 需要求出 B中的每一个字符串, 是否是A中某一个字符串的子串. 也就是拿到80w个bool值. 当然, 直观的看上去, 有一个暴力的解法, 那就是 双重循环, 再调用字符串德contains方法, 想法很美好, 现实很残酷. 如果你真的这么实现了(是的, 我做了.), 就会发现,效率低到无法接受.具体的效率测评在后文给出...

呼延十 1288

EGE基础入门篇(一):绘图基础知识

EGE绘图所需要了解的相关基础知识

依稀_yixy的博客 2万+

后缀数组 详解(1)

点击这里即可获取,包括答案解析。持续更新!**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)点击这里即可获取,包括答案解析。[外链图片转存中…(img-CKNeNhIU-1713204794561)]

2401_84097883的博客 825

告别OLE!Delphi操作Excel的3种轻量级方案横向评测(FlexCel/XLSReadWriteII/LibXL)

本文深入评测了Delphi操作Excel的三种轻量级方案:FlexCel、XLSReadWriteII和LibXL。通过技术架构、API设计、性能测试和实战案例的全面对比,帮助开发者选择最适合的工具,提升Excel文件处理效率,告别传统OLE方案的依赖和性能问题。

onion的博客 932

CentOS7下用FreeRADIUS+AD实现802.1X认证完整指南(附华为交换机配置)

本文提供了在CentOS 7系统上部署FreeRADIUS并与Windows Active Directory集成,以实现企业级802.1X网络认证的完整实战指南。内容涵盖从架构原理、服务器配置(包括Kerberos、Samba Winbind集成)、FreeRADIUS核心设置与AD联动,到华为交换机的详细配置步骤。重点解决了生产环境中常见的高可用、动态VLAN下发及深度排错问题,为企业构建集中、安全的网络准入控制体系提供了经过验证的解决方案。

weixin_29273849的博客 407

字符串匹配(三)----后缀数组算法

一、什么是后缀数组:   字符串后缀Suffix 指的是从字符串的某个位置开始到其末尾的字符串子串。后缀数组 Suffix Array(sa) 指的是将某个字符串的所有后缀按字典序排序之后得到的数组,不过数组中不直接保存所有的后缀子串,只要记录后缀的起始下标就好了。   比如下面在下面这张图中,sa[8] = 7,表示在字典序中排第9的是起始下标为7的后缀子串,这里还有一个比较重要的数组ran...

weixin_30443895的博客 300

07群晖Docker部署nousresearch/hermes-agent

群晖Docker部署nousresearch/hermes-agent。

分享技术,传播知识! 1391

后缀数组:字符串处理的强大工具

后缀数组是对字符串的所有后缀进行排序后,得到的一个排名和原下标的映射数组。具体来说,对于一个字符串,它的后缀是指从某个下标开始到字符串末尾的子串。例如,对于字符串 “ABABABB”,它的后缀包括 “ABABABB”、“BABABB”、“ABABB”、“BABB”、“ABB”、“BB”、“B”。将这些后缀按照字典序排序后,我们可以得到一个排名数组,其中每个元素表示对应后缀在排序后的位置。后缀数组作为一种重要的字符串处理工具,在字符串匹配、分析等方面具有广泛的应用。

m0_57836225的博客 750

多台树莓派(主机)通信

在做无人机实验时,有个任务需要 两台无人机 或 无人机与小车 进行通信。 由于我们飞机上用了树莓派,相当于一台电脑,索性选用Socket网络编程。 条件:树莓派、局域网(手机热点或路由器)。需要通信的两台树莓派接入同一个局域网。 如若现场没有网络,可将树莓派配置为无线路由器,发射wifi。网上很多教程,注意一点是树莓派需要先用网线接入路由器再配置。 发送数据: # -*- coding...

LNL_LNL的博客 7689

【ArcGIS微课1000例】0149:Geographic Imager6.6下载安装教程

首先保证电脑上安装对应版本的PS软件,笔者安装的是PS2023(V24.7)版本,然后安装本软件。保持以上窗口运行状态,然后打开PS,自动弹出如下窗口。勾选【Automatically checkout LIcense】,点击Close。双击setup开始安装,点击【确认】,一路默认安装到底。驱动器:DVD-ROM驱动器(用于DVD版本)处理器:2GHz或更快的英特尔或AMD处理器。安装完成后,将Crack中的所有文件拷贝到。硬盘:600 MB的可用硬盘空间用于安装。内存:4GB内存(建议8GB或更高)。

智慧空间实验室 1221

IO竞赛字符串算法专题解析

字符串是IO竞赛中非常重要的数据类型,在各类算法题中都有广泛的应用。掌握字符串处理的高效算法和技巧,对于解决IO竞赛中的问题至关重要。本文将深入解析IO竞赛中常用的字符串算法,包括字符串的基础操作、字符串匹配算法、字符串哈希、字典树、后缀数组等,并通过具体的代码实现和实例分析,帮助读者理解和掌握这些算法。

欢迎来到智能安全前线!这里是AI与信息安全交汇之地。我们以代码为武器,深入大模型攻防实战,破解系统漏洞。追踪OpenAI、Meta前沿动态,用红蓝对抗思维,锻造智能时代的坚盾与利矛。 3297

EMC设计技巧及经验总结3:TVS的使用

Way back in undergrad circuits class(回到本科时的电路课程), our TA(助教) loved to give uslittle “black box” circuits. We’d measure the voltage and current characteristics, then have to determine what compone

snmplink的博客 2411

第五章 串和KMP匹配算法

一、串的定义 串(string)是由零个或多个字符组成的有限序列,又名叫字符串。 一般记作: s="a1a2a3...an"; 字符串的基本操作方法: 二、串的存储结构 1.串的顺序存储结构:串的顺序存储结构是用一组地址连续的存储单元来存储串中的字符序列的。 2.串的链式存储结构:总的来说不如顺序存储灵活,性能也不如顺序存储结构好。 三、朴素的模式匹配算法 子串的定位操作通常称

张亚运的专栏 1187

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

第五章 字符串专题(下)

1、后缀数组 我在这里写的实在不形象,,推荐一篇blog吧,https://www.cnblogs.com/xiaoyh/p/10322424.html import java.util.Arrays; class test3{ public static void main(String[] args) { match(); } static ...

h_666666的博客 307

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

《算法与数据结构》第五章[算法]:串的模式匹配算法

本文大家将认识字符串模式匹配的两种算法:朴素模式匹配算法和KMP算法。朴素算法通过主串和模式串的双重循环进行匹配,时间复杂度最坏为O((n-m+1)m)。KMP算法通过分析模式串内部重复结构,避免不必要的回溯,提高匹配效率。文章以具体示例演示了两种算法的匹配过程,并说明了KMP算法的优化思路,即利用已匹配部分的信息减少比较次数。

NixLockhart的博客 1097

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

第五章 字符串专题 ---------------- 字符串匹配(二)----KMP算法

什么是KMP算法:   KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。 先来看...

Curtis’Blog 312

第五章 字符串

正式进入字符串学习时,先来了解一下这节的主要内容有什么,大家请看:字符串基本概念字符串的存储结构字符串的运算实现字符串的模式匹配看起来内容不多,让我们一一来学习吧!

2302_80273839的博客 457

图解算法:KMP算法

目录第一章 暴力匹配实现第二章 KMP算法介绍第三章 KMP算法原理第四章 KMP的匹配表第五章 KMP算法实现 项目地址:https://gitee.com/caochenlei/algorithms 第一章 暴力匹配实现 【问题描述】 有一个字符串 str1 = “BBC ABCDAB ABCDABCDABDE”,和一个子串 str2 = “ABCDABD”,现在要判断 str1 是否含有 str2,如果存在,就返回第一次出现的位置,如果不存在,就返回-1。 【问题思路】 【代码实现】 publ

轻松的小希 8311

算法C++ KMP子字符串查找算法理解+示例代码(第五章)

#include <iostream> #include <vector> using namespace std; void getnext(auto& next,const auto& pattern) { int size = pattern.size(); for(int i=1;i<size;++i) { if(next[i-1] && pattern[i] == pattern[next[i.

Love 6's Private Blog 860

第五章 BF算法和KMP算法

BF算法#include<iostream> #include<cstring> using namespace std;//时间复杂度O(n*m) int BF_match(char *s,char *t){ int len1=strlen(s),len2=strlen(t); if(len1<len2) return -1; for(int i=0;i<=len1-len

ccnuacmhdu的博客 1025

模式匹配算法Leedcode-strStr()

模式匹配算法 实现 strStr() 函数。 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。 题目链接:https://leetcode-cn.com/classic/problems/implement-strstr/description/ 参考《大话数据结构》第五章 KMP算法就是为了不必要的回溯不发生。 一、朴素的模式匹配算法 最好情况:每次都是首字母不匹配,O(

qq_45021488的博客 160

kmp匹配算法介绍及实现

KMP匹配算法 最近在看程杰的《大话数据结构》一书,看到了第五章,这一章介绍了对串进行匹配的算法,包括朴素模式匹配算法和KMP模式匹配算法。对于KMP算法自己也是搞得有点晕乎了,在这里记录下,以后说不定彻底弄懂了就回来补上。 KMP算法是由D.E.Knuth、J.H.Morris和V.R.Pratt三位前辈共同发表的一个模式匹配算法,该算法可以大大避免重复遍历的情况。 我们把要查找的字符串...

liuqingshuige的博客 274

Python实现KMP算法-字符串匹配和查找

《大话数据结构》一书第五章介绍了字符串的定义、存储结构和模式匹配算法。关于模式匹配,重点介绍了暴力(Brute-Force)算法和KMP算法,暴力算法较为简单,但性能较低。KMP算法在暴力算法基础上,通过特别巧妙的方式,降低了字符串比较次数,将时间复杂度从O((n-m+1)*m)降低到了O(n+m)。 但是!!!这本书中关于KMP算法的介绍冗长、混乱,讲解的不够透彻,只讲其一,不讲其二,非常不便于理解。在反复阅读和理解消化了几个小时后,发现对KMP算法还是不能了然于胸。 因此在网上查阅了相关资料,个人感觉讲

明月清風 588

C语言数据结构(大话数据结构——笔记3)第五章:串(字符串)

文章目录串的定义(153)空串 null string(153)子串与主串(153)串的比较(154)串的抽象数据类型(156)查找子串第一个实现方法(157)串的顺序存储结构(157)串的链式存储结构(159)朴素的模式匹配算法(160)(查找效率可能低下,最严重可达O(n^2))串的模式匹配:子串的定位操作(160)KMP模式匹配算法(克努特——莫里斯——普拉特算法)(163) 串的定义(153) 串(string)是由零个或多个字符组成的有限序列,又名叫字符串 空串 null string(153)

Dontla的博客 1190

图解KMP算法(C++实现)

需求提出给定一个模式串 pattern = “ddywabcdababcdabd” 和一个子串 substr = “abcdabd”,需判断 pattern 中是否包含 substr,如果包含,返回 substr 第一次在 pattern 中出现的位置;如果不包含,返回 -1(常用手段)赶时间的小伙伴可以拿去应急了。

qq_43700779的博客 937
上一篇: 第五章 字符串专题 ---------------- 字符串匹配(二)----KMP算法
下一篇: C++中const的用法
Estrellas_
博客等级 码龄9年 273粉丝 233原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值