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;
    }
  • 相关阅读:
    决策树
    性能测试–性能监视器
    MEAN栈开发
    Android Studio 入门(转)
    提取重复代码不应该只从代码角度,可以从业务角度看看(转)
    我眼中的领域驱动设计(转)
    网格最短路径算法(Dijkstra & Fast Marching)(转)
    Android GridView显示SD卡的图片
    Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题
    Android 弹出框Dialog并缩放图片
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2473369.html
Copyright © 2011-2022 走看看