精华内容
下载资源
问答
  • 文本匹配是自然语言处理中的...01常用方法深度学习广泛应用之前,传统文本匹配任务基本采用特征提取的方式,这种方法可解释性好,但需要依赖人工进行特征选择和尝试,泛化能力一般。自从深度学习开始被广泛应用,文...

    10951d56eeea48d36d49390df602fb18.png

    文本匹配是自然语言处理中的一个重要问题,它一个很宽泛的概念,通常研究两段文本之间关系的问题都可以看做是文本匹配。但是在不同场景下,匹配的定义可能差别很大,因此文本匹配并不是一个独立的研究方向,不过很多问题可以抽象成文本匹配问题。

    01常用方法

    深度学习广泛应用之前,传统文本匹配任务基本采用特征提取的方式,这种方法可解释性好,但需要依赖人工进行特征选择和尝试,泛化能力一般。自从深度学习开始被广泛应用,文本匹配也得到了很好的发展,可以大致分为以下几个主要方向:

    1. 单语义模型,通过神经网络给两个句子分别编码,然后计算句子之间的相似度,最经典的代表是2013年微软提出的DSSM[1]。
    2. 多语义模型,改善了单语义模型单一粒度的问题,将整个文本分为不同级别的表达方式,例如词、短语、句子,也会考虑到句子的局部结构[2],编码表达信息比单语义模型更加丰富。
    3. 匹配矩阵模型,借用了图像的矩阵表示方式[3],将文本匹配的交互方式定义为匹配矩阵,因此可将匹配精细到两两词,甚至两两字母之间。
    4. 句子交互模型,主要包括表征层和交互层,应用注意力(attention)机制来挖掘句子内和句子间内容的联系,从而得到更好的效果[4]。

    02行业应用

    有很多真实场景都应用到了文本匹配问题,例如搜索引擎、智能问答、知识检索、对话系统等等,这些场景都需要面临一个问题,从大量的数据库中,选取与用户输入内容最匹配的文本。根据文本长度不同,可以讲语义匹配分为三类:

    1.短文本-短文本匹配;

    2.短文本-长文本匹配;

    3.长文本-长文本匹配。

    第一类短文本-短文本匹配在工业界应用场景广泛,例如网页搜索(比如同款商品搜索),需要计算用户查询和网页标题的匹配程度,从而进行页面召回和排序。

    第二类短文本-长文本匹配是大家平时生活中接触最多的一类应用,比如搜索引擎、智能问答、知识检索,需要计算用户输入与整个页面文本内容之间的相似度。

    第三类长文本-长文本匹配在推荐系统中经常用到,比如新闻推荐,通过抽象整个长文本内容信息,来识别同领域或同事件的相似文本。

    03 行业应用实例

    下面我们以智能客服的例子,讲解一下文本匹配技术的应用环节。智能客服的一般流程包括:

    1)对请求解析理解并补全;

    2)召回FAQ库中的相关问题;

    3)问题排序并返回给客户;

    4)反馈系统记录用户点击行为进行模型更新。

    其中第二步“召回FAQ库中的相关问题”则是整个流程中的关键,衡量用户请求与FAQ库中问题的相似度需要对其语义进行深度解析,同样的问题可能表达方式千差万别,如何降低用户表达与FAQ库中数据表达方式之间的差别则显得尤为关键,也是文本匹配中的难题。

    References:

    [1] Huang, Po-Sen, et al. "Learning deep structured semantic models for web search using clickthrough data.", CIKM 2013;

    [2] Yin, Wenpeng, and Hinrich Schütze. "Multigrancnn: An architecture for general matching of text chunks on multiple levels of granularity.", ACL 2015;

    [3] Pang, Liang, et al. "Text matching as image recognition.", AAAI 2016;

    [4] Kim, Seonhoon, Inho Kang, and Nojun Kwak. "Semantic sentence matching with densely-connected recurrent and co-attentive information.", AAAI 2019。

    展开全文
  • 难度:★★★☆☆类型:字符串方法:桶力扣链接请移步本题传送门更多力扣中等...示例:输入:S = "abcde"words = ["a", "bb", "acd", "ace"]输出: 3解释: 有三个是 S 的子序列的单词: "a", "acd", "ace"。注意:所有在...

    难度:★★★☆☆

    类型:字符串

    方法:桶

    力扣链接请移步本题传送门

    更多力扣中等题的解决方案请移步力扣中等题目录

    题目

    给定字符串 S 和单词字典 words, 求 words[i] 中是 S 的子序列的单词个数。

    示例:

    输入:

    S = "abcde"

    words = ["a", "bb", "acd", "ace"]

    输出: 3

    解释: 有三个是 S 的子序列的单词: "a", "acd", "ace"。

    注意:

    所有在words和 S 里的单词都只由小写字母组成。

    S 的长度在 [1, 50000]。

    words 的长度在 [1, 5000]。

    words[i]的长度在[1, 50]。

    解答

    我们用桶的思想来解决这个问题。

    准备一个字典,字典的键是26个字母,字典的值是列表,作为该字母对应的桶,这个列表中包含若干字符串,这些字符串是各个单词的尾串,它们的前一个字母就是字典的键。

    我们首先把各个单词放在字典中,例如["a", "bb", "acd", "ace"]这几个单词放在字典中的情况就是{'a': ['', 'cd', 'ce'], 'b': ['b']},其他位置全部是空桶。

    然后我们可以开始遍历参考字符串S中的每个字符,如果当前遍历到的字母在字典中对应的桶不是空的,那么逐个的弹出这个桶中所有的尾串,摘取其头部后将剩余部分放在该头部字母对应的桶中,以备后续的查询。如果遇到尾串已经为空,说明以该尾串对应的单词是S的一个子序列,则可以将计数器加一。

    我们对S只遍历一次,循环的摘掉各个单词的头部字母,并把剩余部分安排在各自的桶中,节省了计算开销,那些遍历S结束后还留在桶中的尾串,它们对应的单词一定不是S的子序列。

    class Solution(object):

    def numMatchingSubseq(self, S, words):

    ans = 0

    head_dict = {chr(i): [] for i in range(97, 97+26)}

    for word in words:

    head_dict[word[0]].append(word[1:])

    for letter in S:

    # print({k: v for k, v in head_dict.items() if v}, letter)

    bucket = head_dict[letter]

    head_dict[letter] = []

    while bucket:

    sub_word = bucket.pop()

    if not sub_word:

    ans += 1

    else:

    head_dict[sub_word[0]].append(sub_word[1:])

    return ans

    如有疑问或建议,欢迎评论区留言~

    有关更多力扣中等题的python解决方案,请移步力扣中等题解析

    展开全文
  • 其实像这个求最大的匹配数的代码还是蛮简单的, 如果你会网络流那么理解起来更加方便了,不懂也没事,你可以自己画一张简单的图,把下面的过程模拟一遍 ,就知道是怎么求找了。下面的代码给出了详细的解释。 linker...

    其实像这个求最大的匹配数的代码还是蛮简单的, 如果你会网络流那么理解起来更加方便了,不懂也没事,你可以自己画一张简单的图,把下面的过程模拟一遍 ,就知道是怎么求找了。下面的代码给出了详细的解释。

    <span style="font-size:18px;">#include
    #include
    using namespace std ;
    #define MAXN 100
    
    bool visit[MAXN] ;//这个数组的目的 是来标记那些点已经被访问过了。
    int map[MAXN][MAXN] ; //用来记录左右两边两个点的的关系。
    int linker[MAXN] ;//用来放那些点已经被连接了 。
    
    int n , m , T ;//分别表示左边与右边的点的数量
    
    void init(){
        //初始化
        memset(map , 0 , sizeof(map)) ;
        memset(linker , -1 ,sizeof(linker)) ;
    
        scanf("%d%d%d" , &n, &m ,&T) ;
        //输入那些点是有联系的
        while(T--){
            int x , y ;
            scanf("%d%d" ,&x , &y ) ;
            map[x][y] = 1 ;
        }
    
    }
    int DfsFind( int x ) {
    
        int i ;
        for(i = 1 ; i <= m ;i++){
        
            if(map[x][i] && !visit[i]){
            
                visit[i] = true ;
                //DfsFind(linker[i]) 这是寻找某点是否有多条边连接,且构成了增广路 。
                if(linker[i] == -1 || DfsFind(linker[i]) ){
                
                    linker[i] = x ;
                    return true ;
    
                }
    
            }
    
        }
        return false ;
    }
    int main(){
    
        init () ;
        int i ,cot = 0;
        for(i = 1 ;i <= n ; i++)
        {
            memset(visit , 0 ,sizeof(visit)) ;//这里要注意 visit 每次都要初始化的
            if(DfsFind(i))
                cot++ ;        
        }
        printf("%d\n" , cot ) ;
    
        return 0 ;
    }</span>



    展开全文
  • KMP模式匹配算法

    2018-07-19 07:39:36
    很好的解释了,当字符不等时,模式换的j指针,应该怎么指向。 http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 阮一峰字符串匹配的KMP算法   转:http://bl...

    https://www.cnblogs.com/yjiyjige/p/3263858.html

    很好的解释了,当字符不等时,模式换的j指针,应该怎么指向。

    http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

    阮一峰字符串匹配的KMP算法

     

    转:http://blog.csdn.net/fightlei/article/details/52712461

    做个记录,建议查看原创,排版更好。

     

    首先我们需要了解什么是模式匹配?

    子串定位运算又称为模式匹配(Pattern Matching)或串匹配(String Matching)。在串匹配中,一般将主串称为目标串,将子串称为模式串。本篇博客统一用S表示目标串,T表示模式串,将从目标串S中查找模式串T的过程称为模式匹配。

    虽然我们的主角是KMP模式匹配算法,但我们还是要先从暴力匹配算法讲起,通过发现暴力匹配算法存在的问题,由此来引出KMP模式匹配算法。

     

    朴素的模式匹配算法

     

    【基本思想】

    从目标串S的第一个字符开始和模式串T的第一个字符进行比较,如果相等则进一步比较二者的后继字符,否则从目标串的第二个字符开始再重新与模式串T的第一个字符进行比较,以此类推,直到模式串T与目标串S中的一个子串相等,称为匹配成功,返回T在S中的位置;或者S中不存在值与T相等的子串,称匹配失败,返回-1.此算法也称为BF(Brute-Force)算法。

     

    我们先通过一个简单的例子,来了解一下BF算法是怎么回事。假设有一个目标串S为“ababb”,模式串T为“abb”。由于例子比较简单,我们可以绘制出整个的匹配过程。如下图所示:

    可以看到匹配流程完全是按照上面给出的基本思想走下来的,首先从目标串S的第一个字符开始和模式串T的第一个字符进行比较(第一趟),如果相等则进一步比较二者的后继字符(第二趟),否则从目标串的第二个字符开始再重新与模式串T的第一个字符进行比较(第三趟,第四趟)。我们重点来关注一下第三趟,此时,发现S[i] != T[j],则要从目标串S的第二个字符再重新开始,i回溯到i = i - j + 1。因为i - j表示这一趟的起始匹配位置,i - j + 1则意为从这一趟起始比较位置的下一个位置继续进行比较。同时j要回溯到0,即重新与模式串T的第一个字符进行比较。

    【BF算法实现】

     

    
     
    1. /*

    2. * BF匹配算法

    3. */

    4. public static int violentMatching(String s, String t) {

    5. int i = 0;

    6. int j = 0;

    7. while (i < s.length() && j < t.length()) {

    8. if (s.charAt(i) == t.charAt(j)) {

    9. i++;

    10. j++;

    11. } else {

    12. //i回溯到这一趟起始匹配位置的下一个位置

    13. i = i - j + 1;

    14. j = 0;

    15. }

    16. }

    17. //当j==t.length()表示目标串S中的一个子串与模式串T完全匹配

    18. if (j == t.length()) {

    19. //返回这一趟起始匹配位置,即T在S中的位置

    20. return i - j;

    21. } else {

    22. return -1;

    23. }

    24. }

    BF算法的实现比较简单,思维方式也很直接,比较容易理解。但是我们发现存在这样的问题:

    第一趟比较结束后,我们可以发现信息:S[0] =T[0],第二趟比较结束后,得到信息:S[1] = T[1],第三趟后得到信息:S[2] != T[2]。接下来我们通过观察模式串T可以发现T[0] !=T[1]。因此可以立即得出结论T[0] != S[1],所以根本无需进行第四趟的比较。可能由于例子比较简单,无法鲜明的体现出KMP算法的优势,下面我们举一个稍微复杂些的例子来看看:

    假设有一个目标串S为“ababcabcacb”,模式串为“abcac”,当比较到到S[2]与T[2]时出现失配

     

    如果是按照BF算法,则下一趟应从S[1]与T[0]进行比较开始。但是通过上一趟的比较我们是可以发现:S[0] = T[0],S[1] = T[1],S[2] != T[2]。再观察模式串T自身我们发现T[0] != T[1],因此可以立即得出结论S[1] != T[0],所以可以省略它们的比较,直接从S[2]与T[0]进行比较开始:

    从图中可以看到,当比较到S[6]和T[4]时,再次出现失配情况。如果继续按照BF算法,显然又会多进行几次不必要的比较。那么又应该从目标串和模式串的哪两个位置开始进行比较呢?

    从上图可以看出比较结束时,有如下信息:S[2] = T[0],S[3] = T[1],S[4] = T[2],S[5] = T[3],S[6] != T[4]。然后我们在观察模式串T,可以得到:

    (1)T[0] != T[1],因此T[0] != S[3],所以可以省略它们的比较。

    (2)T[0] != T[2],因此T[0] != S[4],省略它们的比较。

    (3)T[0] = T[3],因此T[0] = S[5],当相等时继续比较两个串的后继字符,所以从S[6]和T[1]开始进行比较。

    可以看到应用此方法,只发生了三次重新匹配,就得到了匹配成功的结论,加快了匹配的执行速度。

    上面的例子只是大概描述了方法的思路,但是这种方法到底是什么,到底如何精确的进行描述,以及如何用代码实现呢?下面就来解决这些问题。

     

    KMP模式匹配算法

     

    此算法是由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现的,因此该算法被称为克努斯-莫里斯-普拉特操作,简称为KMP算法。

    KMP算法,是不需要对目标串S进行回溯的模式匹配算法。读者可以回顾上面的例子,整个过程中完全没有对目标串S进行回溯,而只是对模式串T进行了回溯。通过前面的分析,我们发现这种匹配算法的关键在于当出现失配情况时,应能够决定将模式串T中的哪一个字符与目标串S的失配字符进行比较。所以呢,那三位前辈就通过研究发现,使用模式串T中的哪一个字符进行比较,仅仅依赖于模式串T本身,与目标串S无关。

    这里就要引出KMP算法的关键所在next数组,next数组的作用就是当出现失配情况S[i] != T[j]时,next[j]就指示使用T中的以next[j]为下标的字符与S[i]进行比较(注意在KMP算法中,i是永远不会进行回溯的)。还需要说明的是当next[j] = -1时,就表示T中的任何字符都不与S[i]进行比较,下一轮比较从T[0]与S[i+1]开始进行。由此可见KMP算法在进行模式匹配之前需要先求出关于模式串T各个位置上的next函数值。即next[j],j = 0,1,2,3,...n-1。

     

    求解next数组

    根据next数组的特性,匹配过程中一旦出现S[i] != T[j],则用T[next[j]]与S[i]继续进行比较,这就相当于将模式串T向右滑行j - next[j]个位置,示意图如下:

    理解上面这幅图是理解next数组的关键,为了绘图简单,使用k 来表示next[j]。图中,j+1表示模式串T的字符个数,当出现失配情况时,使用T[next[j]]与S[i]进行比较,即图中T[k]与S[i]进行比较。因此右边括起来的是T[0]~T[k]共k+1个字符,因此左边括起来的是j + 1 - (k + 1) = j - k个字符,即向右滑行了j-next[j]个位置。

    当上图中出现失配后可以得到如下信息:

    S[i-j] = T[0],S[i-j+1] = T[1],...,S[i-k] = T[j-k],S[i-k+1] = T[j-k+1],...,S[i-2] = T[j-2],S[i-1] = T[j-1]

    模式串T进行右滑后,如图中所示必须保证:

    S[i-k] = T[0],S[i-k+1] = T[1],S[i-k+2] = T[2],...,S[i-2] = T[k-2],S[i-1] = T[k-1]

    通过上面两个式子可得:

    T[0] = T[j-k],T[1] = T[j-k+1],T[2] = T[j-k+2],...,T[k-2] = T[j-2],T[k-1] = T[j-1]

    它的含义表示对于模式串T中的一个子串T[0]~T[j-1],K的取值需要满足前K个字符构成的子序列(即T[0]~T[k-1],称为前缀子序列)与后K个字符构成的子序列(即T[j-1]~T[j-k],称为后缀子序列)相等。满足这个条件的K值有多个,取最大的那个值。

    由此求解next数组问题,便被转化成了求解最大前缀后缀子序列问题。

    再通过一个例子来说明最大前缀后缀子序列分别是什么?

    对于子串“aaabcdbaaa”,满足条件的K值有1,2,3,取最大K值即3做为next[j]的函数值。此时的最大前缀子序列为“aaa”,最大后缀子序列为“aaa”。

    再比如子串“abcabca”,其相等的最大前缀后缀子序列即为“abca”

    【求解next数组的算法实现】

     

    
     
    1. public static int[] getNext(String t) {

    2. int[] next = new int[t.length()];

    3. next[0] = -1;

    4. int suffix = 0; // 后缀

    5. int prefix = -1; // 前缀

    6. while (suffix < t.length() - 1) {

    7. //若前缀索引为-1或相等,则前缀后缀索引均+1

    8. if (prefix == -1 || t.charAt(prefix) == t.charAt(suffix)) {

    9. ++prefix;

    10. ++suffix;

    11. next[suffix] = prefix; //1

    12. } else {

    13. prefix = next[prefix]; //2

    14. }

    15. }

    16. return next;

    17. }

    代码其实并不复杂,整体思路是分别以T[0]~T[suffix]为子串,依次求这些子串的相等的最大前缀后缀子序列,即next[suffix]的值。

     

    比较难理解的应该是有两处,我分别用1和2标示了出来。我们依次来看。初始化的过程如下图所示,prefix指向-1,suffix指向0,next[0] = -1。

    if条件中prefix = -1成立,所以进入if语句,prefix = prefix+1,suffix = suffix+1,此时直接将next[suffix]赋值为prefix。即next[1] = 0。prefix+1到底代表的是什么?next[suffix]又代表的是什么?

    next[suffix]表示的是不包括suffix即T[0]~T[suffix-1]这个子串的相等最长前缀后缀子序列的长度。意思是这个子串前面有next[suffix]个字符,与后面的next[suffix]个字符相等。

    代码中suffix+1以后值为1,prefix+1以后值为0,next[1]表示的是对于子串“a”,它的相等最长前缀后缀子序列的长度,即为prefix,0。prefix一直表示的就是对于子串T[0]~T[suffix-1]前面有prefix个字符与后面prefix个字符相等,就是next[suffix]

    继续往下走,满足if条件T[0] = T[1],则suffix+1值为2,prefix+1以后值为1,next[2] = 1,表示子串“aa”,有长度为1的相等最长前缀后缀子序列“a”。

     

    继续往下走,满足if条件T[1] = T[2],则suffix+1值为3,prefix+1以后值为2,next[3] = 2,表示子串“aaa”,有长度为2的相等最长前缀后缀子序列“aa”。

    当再继续往下走时会发现T[2] != T[3],不满足条件,则进入了else语句,prefix进行了回溯,prefix = next[prefix],这就遇到了第二个难点,为什么要如此进行回溯呢?

    借用网上的一张图来回答这个问题

    这张图网上很多,但是详细描述这张图的具体含义的却很少。图中的j就对应代码中的suffix,k就对应代码中的prefix,模式串T图中用的P表示。

    现在它们也遇到了这个问题,Pj] != P[k],然后k进行了回溯,变为next[k]。既然prefix能走到k,suffix能走到j,则至少能保证对于子串P[0] ~ P[j-1],前面有k个字符与后面k个字符相等。即图中前后方的蓝色区域。要是满足条件P[k] = P[j]则说明对于子串P[0] ~ P[j],前面有k+1个字符与后面k+1个字符相等。但是现在不满足,则说明对于子串P[0] ~ P[j]不存在长度为k+1的相等最长前缀后缀子序列,可能存在比k+1小的最长前缀后缀子序列,可能是k,可能是k-1,k -2 , k -3 ...或者根本就没有是0。那么我们的正常思路应该是回溯到k再进行判断,不存在k个则再回溯到k-1个,以此类推,那么算法中为什么是直接回溯到next[k]呢?

    为了便于描述,我将图中的不同区域使用大写字母进行标注。前面说过正常思路是不存在k+1个,就回溯到k个进行判断,现在我们来看为什么不回溯到k?当回溯到k时,需要满足的条件是X区域的字符与Z区域的字符相等,而我们已知的是X区域的字符与Y区域的字符相等,若要满足条件,则需要Y区域字符与Z区域字符相等,从图中可以看到,Y区域与Z区域的字符仅相差一位,实际上比较的是Y区域的第一个字符与第二个字符,第二个字符与第三个字符等等,所以除非是Y区域的字符全部相等,是同一个字符,否则是不可能满足条件的。然而当Y区域的字符全部相等时,则X区域的字符也全部相等,那么next[k]就等于k,所以不如直接就回溯到next[k]。

    那为什么直接回溯到next[k]就一定会满足条件呢?

    已知的是X区域等于Y区域,所以B区域一定等于D区域,因为B区域表示X区域的后next[k]个字符,D区域表示Y区域的后next[k]个字符。

    而next[k]的含义就是对于子串P[0] ~ P[k-1],前面有next[k]个字符与后面next[k]个字符相等,即A区域等于B区域,所以可以得到A区域一定等于D区域,因此当下次比较满足条件P[next[k]] = P[j]时,就一定有长度为next[k] + 1的相等最长前缀后缀子序列。

    next数组的求解搞清楚了,接下来我们就可以给出KMP算法的完整实现了

    【KMP模式匹配算法实现】

     

    
     
    1. public static int KMP(String s, String t) {

    2. int i = 0;

    3. int j = 0;

    4. //得到next数组

    5. int[] next = getNext(t);

    6. while (i < s.length() && j < t.length()) {

    7. if (j == -1 || s.charAt(i) == t.charAt(j)) {

    8. i++;

    9. j++;

    10. } else {

    11. //根据next数组的指示j进行回溯,而i永远不会回溯

    12. j = next[j];

    13. }

    14. }

    15. if (j == t.length()) {

    16. return i - j;

    17. } else {

    18. return -1;

    19. }

    20. }

    代码和BF算法很类似,不同的是在进行回溯时,j是根据next[j]进行回溯,i不回溯。

     

     

    KMP算法优化

    上面给出的KMP算法还有一些小问题,比如有一个模式串“aaaaax”,目标串“aaaabcde”。通过上面给出的算法我们很容易得到模式串T的next数组,匹配过程如下图所示:

    可以看到当匹配到S[4]和T[4]时出现失配情况,而根据next数组的指示,next[4],下一步应该比较S[4]和T[3],再次失配,再根据指示,比较S[4]和T[2],再失配,再比较S[4]和T[2],又失配,直到比较到S[0]和T[0]仍然失配,然后next[0] = -1,则表示T中的任何字符都不与S[4]进行比较,下一轮比较从S[5]与T[0]开始进行。对于这种特殊情况,虽然我们使用了next数组,但效率仍然是低下的。当S[4] != T[4]时,由于T[4] = T[3] = T[2] = T[1] = T[0],所以它们都不会与S[4]相等,因此应该直接用T[0]与S[5]进行比较。

    针对这种情况,只需改进next数组的求解过程即可

    【next数组求解算法优化实现】

     

    
     
    1. public static int[] getNext(String t) {

    2. int[] next = new int[t.length()];

    3. next[0] = -1;

    4. int suffix = 0; // 后缀

    5. int prefix = -1; // 前缀

    6. while (suffix < t.length() - 1) {

    7. //若相等或前缀索引为-1,则前缀后缀索引均+1

    8. if (prefix == -1 || t.charAt(prefix) == t.charAt(suffix)) {

    9. ++prefix;

    10. ++suffix;

    11. //改进的地方

    12. if (t.charAt(prefix) == t.charAt(suffix)) {

    13. next[suffix] = next[prefix];

    14. } else {

    15. next[suffix] = prefix;

    16. }

    17. } else {

    18. prefix = next[prefix];

    19. }

    20. }

    21. return next;

    22. }

    改进的地方在于,如果T[suffix] != T[prefix],则仍然遵从之前的处理,next[suffix] = prefix。

     

    若T[suffix] = T[prefix]则可能会出现上面例子所说的特殊情况,使next[suffix] = next[prefix]。其实这就是一个回溯过程,原本应该是next[suffix] = prefix,这里由prefix回溯到了next[prefix]。可以这样理解,当再T[suffix]位置出现失配时,本来按照next数组的指示应采用T[next[suffix]] = T[prefix]进行下一轮比较,但是我们已经得知T[suffix] = T[prefix]所以一定会再次出现失配情况,所以我们下一轮直接使用T[next[prefix]]进行比较。

    展开全文
  • VLOOKUP语法“=VLOOKUP(查找值,数据表,序列数,[匹配条件])”。解释:“=VLOOKUP(找谁,去哪些单元格中查找,找到后想要第几列的数据,找个相似的还是找个一模一样的)”,最后一个参数用“1”表示找个相似的,“0”表示...
  • 括号序列是指由 ‘(’ 和 ‘)’ 组成的序列,假如一个括号序列中,包含相同数量的左括号和右括号,并且对于每一个右括号,在他的左侧都有左括号和他匹配,则这个 括号序列就是一个合法括号序列,如(( ))( )...
  • 这是我建议的解决方案,昨天在我的评论中我无法正确解释.>它从映射信息(例如实体注释)生成模式,然后触发postGenerateSchema事件>它从当前数据库生成模式(通过反向工程)>它比较两个生成的模式,并生成第二个...
  • 我相信大家都被很明显的安排过,连跪之后必有连胜,连胜之后必匹配到练英雄的玩家,王者荣耀玩家都别这个安排过吧,这里给大家解释一下为什么会发生这种事情以及怎么避免这种事情的发生。王者荣耀是具有一个匹配机制...
  • 单个汉字正则匹配

    2019-10-08 09:48:19
    解释:一是ASC码最小的汉字,是19968(4e00),龥的ASC码是40869(9fa5),这其间包括了绝大多数常用和不怎么常用的简繁体字,并不是所有的,不过一般的文章而言足够用来查找文章中的任意汉字了,也有人用﨩,这个...
  • 就自己安装pygmo所出现问题的亲身经历,谈一下安装第三方库时,找不到/匹配不到第三方库时应该怎么去解决的思路。 我当时在安装pymgo时,出现“找不到第三方库或者匹配不到第三方库”的问题,我当时的解决方法: 1....
  •  怎么解释呢?就是有A,B两个集合,要求里面元素尽量1对1匹配。 下面的专业解释摘自 (谁叫我懒呢2333) Renfei's Blog—— 二分图的最大匹配、完美匹配 这篇文章讲无权二分图(unweighted bipartite graph)的...
  • 今天练习java比赛题时,忘记了java的正则表达式怎么用,特地查了一下。觉得用好正则表达式真的是能有意想不到的效果。 Talk is cheap,show you their code //解释内容见注释 import java.util.regex.Matcher; ...
  • 解释: “.*” 表示可匹配零个或多个(′∗′)('*')(′∗′)任意字符(′.′)('.')(′.′),这句话怎么读都读不通顺,理解为(′∗′)('*')(′∗′)匹配成前面的(′.′)('.')(′.′),于是就变成(′..′)('..')(′..′)...
  • 最大权重匹配问题-匈牙利算法

    千次阅读 2020-02-24 20:21:45
    其次,2)从结果入手讲算法,我知道了这个算法然后把这个算法解释给你。 这里我想从问题入手,1)我知道了这个问题;2)然后我要怎么去解这个问题;3)最后我怎么就得到了这个算法。 把自己的理解记录一下,大家一起...
  • 1、正则表达式怎么写 2、匹配数字 上图的正则表达式::&quot;(.+?)&quot;} 其中: ()中的内容是实际的正则表达式 . 表示任意字符 表示匹配一次或者多次 ? 表示匹配到一次就结束 整个表达式的意思就是: ...
  • 之前再定战略,总觉得要多宏大,否则怎么能称之为“战略”。 今天这个说法让我有了更进一步的认知。 一、战略并不高大上 虽然自百度百科对战略的解释:是一种从全局考虑谋划实现全局目标的规划。战略是一种长远的...
  • KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。简单匹配算法的时间复杂度为O(m*n);KMP匹配算法。可以证明它的时间复杂度为O(m+n).。 一.简单匹配算法 先来看一个简单匹配算法的函数: ...
  • 像BERT这样的深度学习模型虽然功能强大,但是可能会返回难以解释的不可预测和/或有偏见的结果。 分析搜索结果时,请做出最佳判断。 为什么? Ctrl-F使用精确的字符串匹配来查找网页中的信息。 字符串匹配本质上是...
  • 只要转化下格式就OK ,这里就不详细解释这两种格式的用法了! 今天把之前做好的模块拿到当地实习,不管怎么测 ,连续测试了好几个存储过程 一直报同样的错误 ,错如下: 然后就跟程序进行测试! 错误提示...
  • 我正在尝试评估/测试我的数据是否符合特定分布。 关于它有几个问题,我被告知要么使用scipy.stats.kstest,要么使用...我的解释有误吗?如果我把它设为单尾分布,那么它的值越大,它们来自同一分布的可能性就越大吗?
  • MySQL-索引全方位解释

    2020-07-15 00:15:59
    在MYSQL中存储引擎用类似的方法使用索引,先在索引中找到对应值,然后根据匹配的索引记录找到对应的数据行。 索引有什么用? 加快检索表中数据,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID。 索引怎么用?...
  • javascript函数的解释

    2011-02-26 11:03:52
    javascript函数的解释解释了具体函数的功能,一、函数JavaScript函数集合 1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4.一个浏览器窗口中的DOM顺序是:...
  •  双目测距属于立体视觉这一块,我觉得应该有很多人踩过这个坑了,但网上的资料依旧是云里雾里的,要么是理论讲一大堆,最后发现还不知道怎么做,要么就是直接代码一贴,让你懵逼。 所以今天我想做的,是尽量给大家...
  • kmp的思路是先分析要匹配的字符串A的内在结构特点,做出一张表格记录他的内部特征,然后匹配的时候就可以根据这个字符串的特征查询已经匹配的信息,对B跳跃式的比较,具体比较方法后面在说,先看看他怎么分析特征的. ...
  • 今天开始推理.. --天河著 2018/10/31 ...1,compare 数据类型表 int 匹配 这是整形数据类型的 2,n个空格将作为分隔符. 3, a 是个变量名 ,先缓冲着. 4, = 证明这语句是赋值语句, 5, value =10; 解析 可以把a...
  • prediciton map size 和 label map size 不匹配时,除了 cropping, resize 等暴力措施,且不采取 bilinear , uppooling, deconvolution 等decoder 结构, 为了实现 dense prediction , 该怎么做...
  • 在 Python 官网下载与你的系统匹配的安装文件,然后安装即可。安装后,你会得到一个 Python 解释器,一个命令行交互环境,还有一个简单的集成开发环境。二、关于 Python 解释器什么是解释器?解释器是用来将你的 ...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 242
精华内容 96
关键字:

匹配怎么解释