其他分享
首页 > 其他分享> > c – 使用后缀数组和LCP(-LR)实现字符串模式匹配

c – 使用后缀数组和LCP(-LR)实现字符串模式匹配

作者:互联网

在过去的几周里,我试图弄清楚如何在另一个字符串中有效地找到字符串模式.

我发现很长一段时间,最有效的方法是使用后缀树.但是,由于这种数据结构在空间上非常昂贵,我进一步研究了后缀数组的使用(使用的空间要少得多).不同的论文,如“后缀数组:一种新的在线字符串搜索方法”(Manber& Myers,1993)指出,搜索子字符串可以在O(P log(N))中实现(其中P是通过使用二进制搜索和后缀数组以及LCP数组,模式的长度和N是字符串的长度.

我特别研究了后一篇论文来理解搜索算法. This answer在帮助我理解算法方面做得很好(顺便提一下,它已经进入了LCP Wikipedia Page).

但我仍在寻找实现此算法的方法.特别是所提到的LCP-LR阵列的构造看起来非常复杂.

参考文献:

曼伯&迈尔斯,1993年:曼伯,乌迪; Myers,Gene,SIAM Journal on Computing,1993,Vol.22(5),pp.935-948,http://epubs.siam.org/doi/pdf/10.1137/0222058

更新1

只是为了强调我感兴趣的东西:我理解LCP数组,并找到了实现它们的方法.但是,“普通”LCP阵列不适合有效的模式匹配(如参考文献中所述).因此,我对实现LCP-LR阵列感兴趣,这似乎比实现LCP阵列复杂得多

更新2

添加了参考文件的链接

解决方法:

可以帮助你的终端:增强后缀数组,用于描述带有各种其他数组的后缀数组,以替换后缀树(lcp,child).

这些可以是一些例子:

https://code.google.com/p/esaxx/ ESAXX

http://bibiserv.techfak.uni-bielefeld.de/mkesa/ MKESA

esaxx似乎正在做你想要的,另外,它有例子enumSubstring.cpp如何使用它.

如果你看一下引用的paper,它会提到一个有用的属性(4.2).由于SO不支持数学,所以没有必要在这里复制它.

我已经快速实现了,它使用了段树:

// note that arrSize is O(n)
// int arrSize = 2 * 2 ^ (log(N) + 1) + 1; // start from 1

// LCP = new int[N];
// fill the LCP...
// LCP_LR = new int[arrSize];
// memset(LCP_LR, maxValueOfInteger, arrSize);
// 

// init: buildLCP_LR(1, 1, N);
// LCP_LR[1] == [1..N]
// LCP_LR[2] == [1..N/2]
// LCP_LR[3] == [N/2+1 .. N]

// rangeI = LCP_LR[i]
//   rangeILeft  = LCP_LR[2 * i]
//   rangeIRight = LCP_LR[2 * i + 1]
// ..etc
void buildLCP_LR(int index, int low, int high)
{
    if(low == high)
    {
        LCP_LR[index] = LCP[low];
        return;
    }

    int mid = (low + high) / 2;

    buildLCP_LR(2*index, low, mid);
    buildLCP_LR(2*index+1, mid + 1, high);

    LCP_LR[index] = min(LCP_LR[2*index], LCP_LR[2*index + 1]);
}

标签:c-3,c,string,pattern-matching
来源: https://codeday.me/bug/20190930/1836852.html