字符串匹配算法总结

2023-11-20

 

转自:http://blog.csdn.net/zdl1016/archive/2009/10/11/4654061.aspx

 


我想说一句“我日,我讨厌KMP!”。
KMP虽然经典,但是理解起来极其复杂,好不容易理解好了,便起码来巨麻烦!
老子就是今天图书馆在写了几个小时才勉强写了一个有bug的、效率不高的KMP,特别是计算next数组的部分。

其实,比KMP算法速度快的算法大把大把,而且理解起来更简单,为何非要抓住KMP呢?笔试出现字符串模式匹配时直接上sunday算法,既简单又高效,何乐而不为?
说实话,想到sunday算法的那个人,绝对是发散思维,绝对牛。当我在被KMP折磨的够呛的时候,我就琢磨,有没有别的好算法呢??琢磨了半天也没想出个所以然来。笨啊,脑子不够发散。

下面贴上一位兄弟写的算法总结,很简单(建议KMP部分就不用看了,看了费脑子)。
参见:http://hi.baidu.com/willamette/blog/item/02bd0b5599c8b4c0b645ae06.html

趁着做Presentation的功夫,顺便做一个总结

字符串匹配:

---willamette

在匹配串中寻找模式串是否出现,注意和最长公共子序列相区别(LCS: Longest Common Substring)


-: Brute Force(BF或蛮力搜索) 算法:

这是世界上最简单的算法了。
首先将匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位。

速度最慢。

那么,怎么改进呢?

我们注意到Brute Force 算法是每次移动一个单位,一个一个单位移动显然太慢,是不是可以找到一些办法,让每次能够让模式串多移动一些位置呢?

当然是可以的。

我们也注意到,Brute Force 是很不intelligent 的,每次匹配不成功的时候,前面匹配成功的信息都被当作废物丢弃了,当然,就如现在的变废为宝一样,我们也同样可以将前面匹配成功的信息利用起来,极大地减少计算机的处理时间,节省成本。^_^

注意,蛮力搜索算法虽然速度慢,但其很通用,文章最后会有一些更多的关于蛮力搜索的信息。


-: KMP算法

首先介绍的就是KMP 算法。

原始论文:Knuth D.E., Morris J.H., and Pratt V.R., Fast pattern matching in strings, SIAM Journal on Computing, 6(2), 323-350, 1977.

这个算法实在是太有名了,大学上的算法课程除了最笨的Brute Force 算法,然后就介绍了KMP 算法。也难怪,呵呵。谁让Knuth D.E. 这么world famous 呢,不仅拿了图灵奖,而且还写出了计算机界的Bible <The Art of Computer Programming>( 业内人士一般简称TAOCP). 稍稍提一下,有个叫H.A.Simon 的家伙,不仅拿了Turing Award ,顺手拿了个Nobel Economics Award ,做了AI 的爸爸,还是Chicago UnivPolitics PhD ,可谓全才。

KMP 的思想是这样的:

利用不匹配字符的前面那一段字符的最长前后缀来尽可能地跳过最大的距离

比如

模式串ababac 这个时候我们发现在c 处不匹配,然后我们看c 前面那串字符串的最大相等前后缀,然后再来移动

下面的两个都是模式串,没有写出来匹配串

原始位置 ababa c

移动之后 aba bac

因为后缀是已经匹配了的,而前缀和后缀是相等的,所以直接把前缀移动到原来后缀处,再从原来的c 处,也就是现在的第二个b 处进行比较。 这就是KMP


-:Horspool算法

Horspool 算法。

当然,有市场就有竞争,字符串匹配这么大一个市场,不可能让BFKMP 全部占了,于是又出现了几个强劲的对手。

第一个登场的是

论文:Horspool R.N., 1980, Practical fast searching in strings, Software - Practice & Experience, 10(6):501-506

Horspool 算法的思想很简单的。不过有个创新之处就是模式串是从右向左进行比较的。很好很强大,为后来的算法影响很大。

匹配串:abcbc sdxzcxx

模式串:cbcac

这个时候我们从右向左进行对暗号,c-c ,恩对上了,第二个b-a ,不对啊,我们应该怎么办?难道就这么放弃么。于是,模式串从不匹配的那个字符开始从右向左寻找匹配串中不匹配的字符b 的位置,结果发现居然有,赶快对上赶快对上,别耽误了。

匹配串:abcbcsd xzcxx

模式串: cbcac

然后继续从最右边的字符从右向左进行比较。这时候,我们发现了,d-c 不匹配啊,而且模式穿里面没有噢,没办法,只好移动一个模式串长度的单位了。

匹配串:abcbcsdxzcxx

模式串:      cbcac

-:Boyer-Moore算法

第二个上来的是Boyer-Moore 算法。

是一个很复杂的算法,当然,虽然理论上时间复杂度和KMP 差不多,但是实际上却比KMP 快数倍,可见实践是检验真理的唯一标准。

原始论文:R.S.Boyer, J.S.Moore, A fast string searching algorithm , Communications of the ACM,20(10):762-772 ,1977

分为两步预处理,第一个是bad-character heuristics ,也就是当出现错误匹配的时候,移位,基本上就是做的Horspool 那一套。

第二个就是good-suffix heuristics ,当出现错误匹配的时候,我还要从不匹配点向左看啊,以前匹配的那段子字符串是不是在模式串本身中还有重复的啊,有重复的话,那么我就直接把重复的那段和匹配串中已经匹配的那一段对齐就是了。再比较

匹配串:abaccba bbazz

模式串:cbadcba

我们看到已经匹配好了cba ,但是c-d 不匹配,这个时候我们发现既可以采用bad-character heuristics ,也可以使用good-suffix heuristics( 模式串:cba dcba ) ,在这种情况下,邪不压正。毅然投奔good 。移动得到

匹配串:abaccbabbaz z

模式串:    cbadcba

可是,我们有时候也发现,已经匹配好的那一部分其实并没有再有重复了的啊。这个时候,我们发现已经匹配好的那串字符串有一部分在开头重新出现了,那么,赶快,对齐吧。

匹配串:abacccb bbazz

模式串:cbadccb

然后得到

匹配串:abacccbbbazz

模式串:     cbadccb

当两种Good-Suffix 出现的时候,取移动距离最大的那个。

对于BM算法,好规则和坏规则,这里讲的不够明确,下面推荐一个讲解非常优秀的文章,可谓图文并茂啊,而且还是个MM写的。
Boyer-Moore 经典单模式匹配算法
http://blog.csdn.net/iJuliet/archive/2009/05/19/4200771.aspx


-:Sunday算法

最后一个是Sunday 算法,实际上比Boyer-Moore 还快,呵呵。长江后浪推前浪。

原始论文:Daniel M. Sunday, A very fast substring search algorithm, Communications of the ACM, v.33 n.8, p.132-142, Aug. 1990

看原始论文的题目,D.M. Sunday 貌似是故意想气气Boyer-Moore 两位大牛似的。呵呵。不过实际上的确Sunday 算法的确比BM 算法要快,而且更简单。

Sunday 的算法思想和Horspool 有些相似,但是。当出现不匹配的时候,却不是去找匹配串中不匹配的字符在模式串的位置,而是直接找最右边对齐的右一位的那个字符在模式串的位置。

比如:

匹配串:abcbc zdxzc

模式串:zbcac

恩,这里我们看到b-a 没有对上,我们就看匹配串中的z 在模式串的位置,然后,嘿嘿。

匹配串:abcbczdxzc

模式串:     zbcac

如果模式串中的没有那个字符怎么办呢?很简单,跳过去呗。

匹配串:abcbc edxzcs

模式串:zbcac

e 不在模式串中出现

那么我们就

匹配串:abcbcedxzcs

模式串:      zbcac

(2009/10/20补充)
RK算法

某一天在图书馆的一本算法分析设计书上翻到的。思路很新颖!和大家分享下。
在串匹配的简单算法中,把文本每m个字符构成的字符段作为一个字段,和模式进行匹配检查。如果能对一个长度为m的字符

串赋以一个Hash函数。那么显然只有那些与模式具有相同hash函数值的文本中的字符串才有可能与模式匹配,这是必要条件

,而没有必要去考虑文本中所有长度为m的字段,因而大大提高了串匹配的速度。因此RK算法的思想和KMP,BM,Sunday等思

路迥然不同!
(事实上,之前的串匹配方法,是将模式串的一个一个字符作为小的特征去分别进行匹配,而RK算法则是将串整体作为一个

特征!难就难在单个字符的特征很容易想得到,整体作为一个特征就没那么容易想得到了)
如果把整体作为一个特征,那么如何快速的求出这个整体特征的特征值??
模式串的特征值仅需求一次即可。对于文本中的任意m个字符构成的字串如何快速的求特征就是个难点了。
抛砖引玉,这里给出一个简单的特征计算。 将字符串的每一个字符看做一个数,那么这个字符串的就是一个数字数组,通

过积分向量可以快速任意一个长度子字符串的向量和。可以把字符串的对应的字符数组的元素和看做这个字符串整体特征。

这个特征是可以再O(1)的时间内求出的。其实原始的RK算法里面是把字符串看做一个26进制数在计算特征的。这里就不啰

嗦了,有兴趣的可以深入查找

aabsee sds 模式串 ees
      ees

发现 see向量和 == ees的向量和
然后就对see和ees做逐个字符的比较。发现不匹配继续往下走
aabsees ds 模式串 ees
        ees
发现 ees向量和 == ees的向量和
然后就对ees和ees做逐个字符的比较。发现匹配OK。

另外还有 字符串匹配自动机 后缀树算法(分在线和非在线两种)等 见如下文章。不能说那个比那个更好,各个算法都有自己的优势及最佳应用场合。参考:
http://blog.csdn.net/yifan403/archive/2009/06/16/4272793.aspx

另外,关于多模式字符串匹配 有AC算法(字符串匹配自动机思想) WM算法(BM在多模式的推广应用)
参考:
http://blog.csdn.net/ijuliet/category/498465.aspx  该女子的blog有很多好文章。

/**********************华丽分割线******************************/
附上sunday代码:
http://hi.baidu.com/kmj0217/blog/item/6f837f2f3da097311e3089cb.html

一种比KMP BM 更高效的匹配算法(如果想看原英文介绍,看下面分割线后的网址)

适用于:模式串较短的情况,最坏时间复杂性为O(N*M),不过一般没这么坏

Sunday 算法其实思想跟BM算法很相似,只不过Sunday算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。如果该字符没有 在匹配串中出现则直接跳过,即移动步长= 匹配串长度+ 1;否则,同BM算法一样其移动步长=匹配串中最右端的该字符到末尾的距离+1。

 

代码如下:

/*

Sunday-字符串匹配算法 -- 一种优于 KMP 的算法

思想类似于BM 算法,只不过是从左向右匹配

遇到不匹配的看大串中匹配范围之外的右侧第一个字符在小串中的最右位置

另外:采用BM/KMP 的预处理的做法,事先计算好移动步长 ,等到遇到不匹配的值直接使用

*/

#include<iostream>

#include<string.h>

using namespace std;

//一个字符8位 最大256种

#define MAX_CHAR_SIZE 256

 

/*设定每个字符最右移动步长,保存每个字符的移动步长

如果大串中匹配字符的右侧一个字符没在子串中,大串移动步长= 整个串的距离 +1

   如果大串中匹配范围内的右侧一个字符在子串中,大串移动距离= 子串长度 - 这个字符在子串中的位置

*/

int *setCharStep(char *subStr)

{

     int *charStep=new int[MAX_CHAR_SIZE];

     int subStrLen=strlen(subStr);

     for(int i=0;i<MAX_CHAR_SIZE;i++)

             charStep[i]=subStrLen+1;

     //从左向右扫描一遍 保存子串中每个字符所需移动步长

     for(int i=0;i<subStrLen;i++)

     {

            charStep[(unsigned char)subStr[i] ]=subStrLen-i;         

     }

     return charStep;

}

/*

   算法核心思想,从左向右匹配,遇到不匹配的看大串中匹配范围之外的右侧第一个字符在小串中的最右位置

   根据事先计算好的移动步长移动大串指针,直到匹配

*/

int sundaySearch(char *mainStr,char *subStr,int *charStep)

{

     int mainStrLen=strlen(mainStr);

     int subStrLen=strlen(subStr);

     int main_i=0;

     int sub_j=0;

     while(main_i<mainStrLen)

     {                  

            //保存大串每次开始匹配的起始位置,便于移动指针

             int tem=main_i;

             while(sub_j<subStrLen)

             {

                    if(mainStr[main_i] ==   subStr[sub_j])

                    {

                            main_i++;

                            sub_j++;

                            continue;                   

                    }                

                    else{

                        //如果匹配范围外已经找不到右侧第一个字符,则匹配失败

                         if(tem+subStrLen > mainStrLen)

                                     return -1;

                         //否则 移动步长 重新匹配

                         char firstRightChar=mainStr[tem+subStrLen];

                         main_i =tem + charStep[(unsigned char)firstRightChar];

                         sub_j=0;   

                         break;//退出本次失败匹配 重新一轮匹配

                    }  

             }

             if(sub_j == subStrLen)

                       return main_i-subStrLen;

     }

     return -1;

}

int main()

{

         char *mainStr="absaddsasfasdfasdf";

         char *subStr="dd";

         int *charStep=setCharStep(subStr);

         cout<<"位置: "<<sundaySearch(mainStr,subStr,charStep)<<endl;

         system("pause");

         return 0;    

}

 

/*************************************************华丽的分割线***************************************/

算法介绍以及实现伪码:http://www-igm.univ-mlv.fr/~lecroq/string/node19.html

void preQsBc(char *x, int m, int qsBc[]) {
   int i;

   for (i = 0; i < ASIZE; ++i)
      qsBc[i] = m + 1;
   for (i = 0; i < m; ++i)
      qsBc[x[i]] = m - i;
}


void QS(char *x, int m, char *y, int n) {
   int j, qsBc[ASIZE];

   /* Preprocessing */
   preQsBc(x, m, qsBc);

   /* Searching */
   j = 0;
   while (j <= n - m) {
      if (memcmp(x, y + j, m) == 0)
         OUTPUT(j);
      j += qsBc[y[j + m]];               /* shift */
   }
}


// 第三个代码实现,貌似比较高效
http://hi.baidu.com/azuryy/blog/item/10d3d3460b97af0e6b63e5cd.html
头文件定义:
/* Sunday.h */
class Sunday
{
public:
   Sunday();
   ~Sunday();

public:
    int find(const char* pattern, const char* text);

private:
    void preCompute(const char* pattern);

private:
    //Let's assume all characters are all ASCII
    static const int ASSIZE = 128;
    int _td[ASSIZE] ;
    int _patLength;
    int _textLength;
};


源文件
/* Sunday.cpp */

Sunday::Sunday()
{
}

Sunday::~Sunday()
{
}

void Sunday::preCompute(const char* pattern)
{
    for(int i = 0; i < ASSIZE; i++ )
        _td[i] = _patLength + 1;

    const char* p;
    for ( p = pattern; *p; p++)
        _td[*p] = _patLength - (p - pattern);
}

int Sunday::find(const char* pattern, const char* text)
{
    _patLength = strlen( pattern );
    _textLength = strlen( text );

    if ( _patLength <= 0 || _textLength <= 0)
        return -1;

    preCompute( pattern );

    const char *t, *p, *tx = text;

    while (tx + _patLength <= text + _textLength)
    {
        for (p = pattern, t = tx; *p; ++p, ++t)
        {
            if (*p != *t)
                break;
        }
        if (*p == 0)
            return tx-text;
        tx += _td[tx[_patLength]];
    }
    return -1;
}

简单测试下:
int main()

{
    char* text = "blog.csdn,blog.net";
    char* pattern = "csdn,blog"    ;
    Sunday sunday;

    printf("The First Occurence at: %d/n",sunday.find(pattern,text));

    return 1;
}


strstr的实现。
需要说明的是strstr是c语言提供的使用Brute Force实现的字符串匹配,简单、通用是其最大的优点。时间复杂度是O(mn)
// 下面是Microsoft的实现
//经典算法
//比KMP算法简单,没有KMP算法高效
char * __cdecl strstr (
        const char * str1,
        const char * str2
        )
{
        char *cp = (char *) str1;
        char *s1, *s2;
        if ( !*str2 )
            return((char *)str1);
        while (*cp)
        {
                s1 = cp;
                s2 = (char *) str2;
                while ( *s1 && *s2 && !(*s1-*s2) )
                        s1++, s2++;
                if (!*s2)
                        return(cp);
                cp++;
        }
        return(NULL);
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/whoismickey/archive/2009/02/08/3869367.aspx

strstr
  glibc里的strstr函数用的是brute-force(naive)算法,它与其它算法的区别是strstr不对pattern(needle)进行预处理,所以用起来很方便。理论复杂度O
(mn), 实际上,平均复杂度为O(n), 大部分情况下高度优化的算法性能要优于基于自动机的匹配算法,关于串匹配算法可参考http://www-igm.univ-mlv.fr/~lecroq/string/ 。 glibc中使用了(1)Stephen R. van den Berg的实现,在他的基础上,(2)Tor Myklebust http://sources.redhat.com/ml/libc-alpha/2006-07/msg00028.html 给出了更复杂的实现,当然也更高效。
  BF有一个重要性质是事先不用知道串的长度,而基于跳跃的算法是需要用字符串长度来判断结束位置的。如何快速的确定字符串结束位置,可参考http://www.cppblog.com/ant/archive/2007/10/12/32886.html ,写的很仔细。
 将两种思想结合起来,可以做出更快的strstr(3)。约定(1) 为strstrBerg; (2) 为strstrBergo,(3)为lstrstr,(4)为glibc中的strstr,简单测试了一下:
从长度为2k的文本中查找长度为1、2、9的模式串,结果如下
        1               2              9
(1)0.000006 0.000006 0.000012   
(2)0.000007 0.000004 0.000008
(3)0.000002 0.000002 0.000005
(4)0.000005 0.000005 0.000011
下载strstr和测试程序
下载后执行 :
            unzip testStrstr.zip
            cd testStrstr
            make test
基于sse2的strstr函数 是用sse2指令集对strstr的优化
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符串匹配算法总结 的相关文章

  • 生成非连续组合

    我正在尝试创建一个生成器 支持执行 next 的迭代器 可能在 python 中使用yield 它给出来自 1 2 n n 和 r 是参数 的 r 元素的所有组合 这样在选出的r个元素 没有两个是连续的 例如 对于 r 2 且 n 4 生成
  • 在 Python 中删除表达式树及其每个子表达式树中第一个元素周围的括号

    目标是实现简化操作 删除表达式树及其每个子表达式树中第一个元素周围的括号 其中表达式作为括在各个括号中的字符串输入给出 这必须适用于任意数量的括号 例如 12 3 45 6 gt 123 45 6 删除 12 周围的括号 然后删除 45 周
  • 找到两个移动物体的更好交点

    我想极大地优化我的算法之一 我将尽力以最好的方式解释它 主题 我们当时处于二维欧几里德系统中t 0 在这个系统中有两个对象 O1 and O2 O1 and O2分别位于点PA and PC O1移动于常数和已知点方向的速度PB 当物体到达
  • 无痛“算法分析”培训? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我在大学时曾有过一次关于 算法分析 课程的痛苦经历 但最近发现在大学中需要它真实世界 无论如何 我正在
  • 如何选择部分密集数据集的均匀分布子集?

    P是一个 n d 矩阵 持有nd 维样本 P某些地区的密度是其他地区的几倍 我想选择一个子集P其中任意样本对之间的距离大于d0 并且我需要将其传播到整个区域 所有样本都具有相同的优先级 无需优化任何内容 例如覆盖面积或成对距离之和 这是执行
  • 算法:最大计数器

    我有以下问题 您有 N 个计数器 最初设置为 0 并且您对它们有两种可能的操作 increase X 计数器 X 加 1 max counter 所有计数器都设置为任何计数器的最大值 给出一个包含 M 个整数的非空零索引数组 A 该数组代表
  • 优雅的折线“左移”测试

    Given X Y 坐标 即车辆的位置 X Y 数组 它们是折线中的顶点 请注意 折线仅由直线段组成 没有圆弧 我想要的是 计算车辆是在折线的左侧还是右侧 当然还是在顶部 我的做法 迭代所有线段 并计算到每个线段的距离 然后 对于最近的段
  • 当目标是查找某个字符串的所有出现情况时,KMP 最坏情况的复杂度是多少?

    我还想知道哪种算法在查找另一个字符串中所有出现的字符串时具有最坏情况的复杂性 博耶 摩尔算法似乎具有线性时间复杂度 KMP 算法在查找字符串中所有出现的模式时具有线性复杂度 如 Boyer Moore 算法1 如果您尝试在 aaaaaaaa
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做
  • 稀疏矩阵中的最大和子矩形

    求一个子矩形中的最大和NxN矩阵可以完成O n 3 正如其他帖子中指出的 使用 2 d kadane 算法的时间 然而 如果矩阵是稀疏的 具体来说O n 非零条目 可以O n 3 时间被打败了吗 如果有帮助的话 对于我感兴趣的当前应用程序
  • 如何设置K-means openCV c++的初始中心

    我正在尝试使用 OpenCv 和 Kmeans 对图像进行分割 我刚刚实现的代码如下 include opencv2 objdetect objdetect hpp include opencv2 highgui highgui hpp i
  • 交换两个向量之间的值,使两个向量的 max_element 之和最小

    这是 Codechef 的问题 但请耐心等待 https www codechef com ZCOPRAC problems ZCO16001 https www codechef com ZCOPRAC problems ZCO16001
  • 加密成本高,解密成本低

    我希望该用户 攻击者加密数据并发送给服务器 现在我想要一种与标准算法完全相反的算法 使用快 难以解密 即很难使用服务器发送的密钥来加密密码等数据 以防止随机攻击 但很容易解密这样服务器在验证用户时消耗的时间非常少 但是对于攻击者来说 每次使
  • 哪种数据聚类算法适合检测时间序列事件中未知数量的聚类?

    这是我的场景 考虑在不同地点和时间发生的一组事件 例如 考虑有人在高空记录暴风雨期间城市中的雷击 就我的目的而言 闪电是瞬时的 只能击中某些位置 例如高层建筑 还可以想象每次雷击都有一个唯一的 ID 以便以后可以参考该雷击 这个城市大约有1
  • Java:如何实现3和?

    我正在研究 3 Sum 来自己实现它 并遇到了以下规则的实现 给定一个由 n 个整数组成的数组 S S 中是否存在满足 a b c 0 的元素 a b c 查找数组中所有总和为零的唯一三元组 注意 三元组 a b c 中的元素必须按非降序排
  • 从日志文件中获取前 100 个 URL

    我的一位朋友在接受采访时被问到以下问题 谁能告诉我如何解决它 我们有一个相当大的日志文件 大约 5GB 日志文件的每一行都包含一个用户在我们网站上访问过的 URL 我们想要找出用户访问最多的 100 个 URL 怎么做 如果我们有超过 10
  • 字符串排序真的是 O(n^2logn) 吗? [复制]

    这个问题在这里已经有答案了 我读了以下内容 排序需要 O NlogN 那么它怎么是 O N 2logN 我们在这里想念的是 两个字符串的比较不是 O 1 在最坏的情况下 需要 在 所以最终的复杂度是O N 2logN 它是否正确 我一直认为
  • 编程 Pearls - 随机选择算法

    Programming Pearls 第一版第 120 页介绍了从 N 个整数总体中选择 M 个等概率随机元素的算法 InitToEmpty Size 0 While Size lt M do T RandInt 1 N if not Me
  • 如何高效地在屏幕上精确绘制N个点?

    这听起来是一个简单的问题 但我发现要获得良好的性能是非常棘手的 我提出的第一个算法是随机绘制点 从一组中检查是否已绘制 否则绘制 如果我们只绘制几个点 那么这种方法效果很好 但当我们接近填满屏幕时 速度会灾难性地减慢 我想出的最好的方法是构
  • 图中的后边

    I m having a hard time understanding Tarjan s algorithm for articulation points I m currently following this tutorial he

随机推荐

  • 语音活性检测器 webrtcvad

    目录 概述 安装 使用脚本 1 测试静音片段 2 清理静音片段 概述 WebRTC是一个免费 开放的框架 项目 使web浏览器通过简单的JavaScript api接口实现实时通信功能 WebRTC An open framework fo
  • 动态规划之多重背包模型

    前置知识 01背包问题 动态规划之01背包模型 如何何何的博客 CSDN博客 完全背包问题 动态规划之完全背包模型 如何何何的博客 CSDN博客 多重背包问题 给定一个有一定容量的背包 和 n 个物品 每个物品有 si 件 每个物品有其对应
  • taoCMS v3.0.2 任意文件上传漏洞(CVE-2022-23880)

    靶标介绍 taoCMS v3 0 2 文件管理处存在任意文件上传漏洞 攻击者可执行任意代码 漏洞复现 1 使用御剑扫描后台 或者直接输入 admin 就会跳转到登录界面 弱口令尝试 账号admin 密码tao 2 在文件管理处 新建文件为1
  • CVPR 2023

    点击下方卡片 关注 CVer 公众号 AI CV重磅干货 第一时间送达 点击进入 gt 计算机视觉和Transformer 交流群 作者 Oliiiver 源 知乎 编辑 CVer公众号 https zhuanlan zhihu com p
  • 使用TensorFlow Lite将深度学习模型部署到IOT系统

    使用TensorFlow Lite将深度学习模型部署到IOT系统 TensorFlow Lite简介 移动设备深度学习框架是部署在手机或者树莓派等小型移动设备上的深度学习框架 可以使用训练好的模型在手机等设备上完成推理任务 这一类框架的出现
  • yolov5--完全炼丹指南

    目录 前言 炼丹方法 收集数据集 划分数据集 yolov5模型训练 简单提升训练效果的措施 关于参数的说明 结语 前言 最近在做yolov5识别手势的项目 爬了很多坑 也排除了不少bug 记录一下 参考前人的经验 遇到写得好的文章我会推荐
  • 打印出1-10000之间的所有对称数(如121,1331,2442)。

    练习题 打印出1 10000之间的所有对称数 如121 1331 2442 自己写的代码 var isSym function num var str for var i 1 i lt 9 i 如果个位算 可去掉注释 str i str f
  • 干掉广告和钓鱼,这款神器绝了!

    大家好 我是良许 前几天 搜狐丢人丢大发了 自家的员工居然遭遇了钓鱼诈骗 据报道 某员工使用邮件时被意外钓鱼导致密码泄露 进而被冒充财务部盗发邮件 共有 24 名员工被骗取 4 万余元 要知道 搜狐可是国内最早的四大门户网站之一 同时也是国
  • 【9.19】正则表达式——sed、awk

    9 19 正则表达式 sed awk 9 4 9 5 sed 1 sed 匹配 2 sed打印具体行数 3 sed 替换功能 9 6 9 7 awk 1 awk 匹配 2 awk 数学运算表达式 3 两个字段比较大小 4 内置变量 OFS
  • Vue (三) 生命周期--钩子函数

    生命周期 Vue官网生命周期的描述 钩子函数 1 beforeCreate 创建Vue实例化之前所调用的函数 div h1 message h1 div
  • webpack高版本configuration.module has an unknown property ‘loaders‘

    webpack更换高版本后报错 webpack cli Invalid configuration object Webpack has been initialized using a configuration object that
  • ffmpeg已支持解码avs2.0

    https ffmpeg org pipermail ffmpeg devel 2016 November 202446 html PS 目前应该还是个提交的patch 待审核
  • 二叉搜索树(BST)的基本操作

    二叉搜索树 BST 的创建 增加 删除 查找 需要注意 BST的左子树必小于根 右子树必大于根 所以不存在值相同的结点 include
  • 计算机网络(自顶向下方法)中的PoP

    目录 前言 问题 解决 前言 在读 计算机网络 自顶向下方法 时 看到在讲网络结构的时候提到过PoP 但是其中有一句话始终不理解 不通顺 上网搜索也没发现相关解释文章 因此 在我把这个问题解决后 就写下了这篇文章 希望可以帮助到其他人 问题
  • Eclipse常用插件下载地址

    Eclipse常用插件下载地址 官方网站http www eclipse org downloads index php下载eclipse的最新版本 Eclipse 项目资源中心 http www ibm com developerwork
  • 2、Java 环境搭建

    Java 环境搭建 1 JDK 的简介 JDK Java Development Kit 是一组实现Java程序开发与运行的本地环境 在实际的项目的开发与运行过程之中 往往都会选择一些比较好用的桌面系统 Windows MacOS 进行开发
  • linux下定时器timer_create()的使用

    一 采用新线程派驻的方式 注 编译时 需加上 lrt include
  • Spring IoC依赖注入的实现

    看了 spring技术内幕 的第二章 学习了spring的IoC容器的实现 对其做了浅显地分析 依赖注入的时机 如果配置文件有配置lazy init 那么依赖注入的时机发生在用户向IoC 容器索取bean的时候 即调用beanfactory
  • Django基础2——URL路由系统

    文章目录 一 基本了解 二 url路由分发 三 正则匹配 四 压缩归档超链接 优化一 使用分组名称功能 优化二 使用url名称功能 4 1 使用功能之前效果展示 4 2 使用功能之后效果展示 一 基本了解 概念 路由系统就是URL路径和视图
  • 字符串匹配算法总结

    转自 http blog csdn net zdl1016 archive 2009 10 11 4654061 aspx 我想说一句 我日 我讨厌KMP KMP虽然经典 但是理解起来极其复杂 好不容易理解好了 便起码来巨麻烦 老子就是今天