• sunday 算法--解决字符串匹配问题


    一、Sunday 匹配机制
    匹配机制非常容易理解:

    目标字符串 haystack,长度为len

    模式串 needle,长度为len_pattern

    当前查询索引 idx (初始为 0)

    待匹配字符串 search= haystack.substring(idx, idx + len_pattern),即从idx下标开始取长度len_pattern的字符串;

    每次匹配都会从目标字符串中提取待匹配字符串模式串进行匹配:

    若匹配,则返回当前 idx

    不匹配,则查看待匹配字符串的后一位字符 c:

    若c存在于模式串 needle中,则 idx = idx + 偏移表[c]

    否则,idx = idx + len(needle)

    Repeat Loop 直到 idx + len(needle) > len(haystack)

    二、偏移表

    偏移表的作用是存储每一个在 模式串 中出现的字符,在 模式串 中出现的最右位置到尾部的距离 +1+1

    三、举例
    String: checkthisout
    Pattern: this

    Step 1:

    idx = 0
    待匹配字符串为:chec
    因为 chec != this
    所以查看 chec 的下一个字符 k
    k 不在 Pattern 里
    所以查看 偏移表,idx = idx + 5
    Step 2:


    idx = 5
    待匹配字符串为:this
    因为 this == this
    匹配,所以返回 5
    四、算法分析
    最坏情况:O(nm)
    平均情况:O(n)

    代码:

    public static int sunday(String haystack, String needle) {
        // 几种特殊情况,快速剪枝
    if (haystack.equals(needle) || needle.isEmpty()) return 0;
    if (needle.length() > haystack.length()) return -1;
    int idx = 0;
    int len_pattern = needle.length();
    int len_search = haystack.length();
    int len = len_search;
    while (len_search >= len_pattern && idx + len_pattern <= len) {
    String sub = haystack.substring(idx, idx + len_pattern);
    if (sub.equals(needle)) return idx;
    else {
    int pos = getPos(haystack.charAt(idx + len_pattern == len ? idx + len_pattern - 1 : idx + len_pattern), needle.toCharArray());
    if (pos == -1) {
    idx += len_pattern + 1;
    } else {
    // 找到字符
    idx += len_pattern - pos;
    }
    len_search = len - idx;
    }
    }

    return -1;
    }

    public static int getPos(char ch, char[] tmp) {
    for (int i = tmp.length - 1; i >= 0; i--) {
    if (tmp[i] == ch) return i;
    }
    return -1;
    }
  • 相关阅读:
    hdu 1181 (搜索BFS,深搜DFS,并查集)
    [置顶] ZSTACK之OSAL_Nv非易失性存储解读上
    Android中利用Fragment显示为两屏
    WCF也可以做聊天程序
    Myeclipse 连接MSSqlServer
    Mysql和Oracle的卸载
    第 5堂作业
    hdu 3421 Max Sum II
    【求助】一个菜鸟java作业,帮忙看一下错在哪儿,题目是判断回文数
    netcat使用
  • 原文地址:https://www.cnblogs.com/majw/p/12134390.html
Copyright © 2020-2023  润新知