zoukankan      html  css  js  c++  java
  • [笔记柔性字符串匹配]ShiftAnd与ShiftOr

    Shift-And 和 KMP一样都是基于前缀搜索的方法,复杂度为O(n);

    《柔性字符串匹配》:

      "只有当模式串小于8时,KMP才比基于后缀和基于子串的搜索方法有效。而在这个范围内,Shift-And算法和Shift-Or算法能够在所有机器上运行,速度至少是Knuth-Morris-Pratt的两倍,并且更易于实现。"

    Shift-And对字母表中的每个字符构造一个位序列,根据下面的公式更新匹配状态D:

    D = ((D<<1) | 0^{m-1}1) & B[t_{i+1}];

    B[t_{i+1}]是字符t_{i+1}的位序列,当D的第j位为1并且t_{i+1}与p_{j+1}相等时,D的第j+1位更新为1,上式中的位或是因为空串也是文本的后缀。

    因为状态表中位序列的有效长度为模式串的长度,所以当模式串长度超过机器字长时,需要构造自定义类型(应该行得通)。

    示例:

    # include <stdio.h>
    # include <string.h>
    
    int b[128];   /* int型共32位,模式串不超过32位 */
    
    int shift_and(char *p, char *t);
    int shift_or(char *p, char *t);
    
    int main()
    {
        char s1[5000], s2[30];
    
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    
        while (~scanf("%s%s", s1, s2))
        {
            printf("shirt-and : %d, shift-or : %d.\n", shift_and(s2, s1), shift_or(s2, s1));
        }
    
        return 0;
    }
    
    int shift_and(char *p, char *t)
    {
        int n, m, i, d, f;
    
        n = strlen(p);
        m = strlen(t);
        memset(b, 0, sizeof(b));
        for (i = 0; i < n; ++i)
        {
            b[p[i]] |= 0x1<<i;
        }
    
        d = 0;
        f = 0x1 << (n-1);
        for (i = 0; i < m; ++i)
        {
            d = ((d<<1) | 0x1) & b[t[i]];
            if (d & f) return i-n+1;    /* 可以根据需要返回第一次匹配结果 */
        }
        return -1;
    }
    
    int shift_or(char *p, char *t)
    {
        int n, m, i, d, f;
    
        n = strlen(p);
        m = strlen(t);
        memset(b, 0xff, sizeof(b));
        for (i = 0; i < n; ++i)
        {
            b[p[i]] &= ~(0x1<<i);
        }
        d = 0xff;
        f = 0x1 << (n-1);
        for (i = 0; i < m; ++i)
        {
            d = (d<<1) | b[t[i]];        /* 可以根据需要返回第一次匹配结果 */
            if (!(d&f)) return i-n+1;
        }
        return -1;
    }
  • 相关阅读:
    iisexpress应用讲解
    Flex document文档 下载网址:
    HDU1407 测试你是否和LTC水平一样高
    HDU1715 大菲波数 Java
    HDU1573 大明A+B Java
    HDU1063 Exponentiation Java
    HDU1754 I Hate It 线段树 链式
    HDU2054 A == B? Java
    HDU1166 敌兵布阵 不完全线段树
    HDU1698 Just a Hook 线段树 Lazy思想
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2473369.html
Copyright © 2011-2022 走看看