單個字元計算hash值的函式為hc(c)
,複雜度為o(1)
多個字元(c1,c2,c3,…,cn)計算hash值的函式設為hstr(c1,c2,c3,...,cn) = hashhc(hc(c1),hc(c2),hc(c3),....,hc(cn))
,hashhc是通過各個字元的hash值來計算整個字串的雜湊值的函式,複雜度為o(n),且不太容易發生hash衝突
計算(c2,c2,c3,…,c(n+1))的hash值的函式為hnext(hstr(c1,c2,c3,...,cn),hc(n+1))
,若hstr(c1,c2,c3,…,cn)已知則複雜度為o(1)
/**
* rk演算法:
* * @author 18118224_周億進
* @since 2020/4/1
*/public class rabinkarpdemo
static int indexof(string str, string regex)
/*** rk演算法:
* 匹配模式串在主串中的位置
* * 這個演算法的難度在於設計hash演算法,
* 假如我們的字符集是自己定義的,只會26位 0-25各代表乙個字母
* 那麼我們完全可以將hash值作為乙個26進製的數字,每一位代表乙個字母,非常高效
* 但是如果我們字符集是utf-8那麼就不能這麼簡單的去設計了.
* * 所以我們是無法完全避免hash衝突的問題,那麼我們就需要將hash值計算得足夠分散,這就要靠大佬了,我是不行
* * 這裡要設計乙個好的hash演算法才能提公升此演算法的效率
* 好的hash演算法會讓hash衝突減少,如果hash衝突非常多,複雜度還是會上公升到o(n*m)
* 如果沒有hash衝突,則複雜度是o(n),因為只對每個字元(char)計算了一次hash就知道所有匹配串的hash值
** @param str 主串
* @param regex 模式串
* @return
*/static int indexof(char str, char regex)
}//如果是最後一次,則不用計算了
if (i < n - m)
}return -1;
}//計算下一位hash的方法
//strcharshash主串上各個位置的hash值
//comparestrhash現在正在匹配的hash值
//i現在正在匹配的str,第一位字元的下標
//m模式串的長度
//返回的是模式串在主串上後移一位的候選字串hash值
//時間複雜度o(1)
private static int hnext(int strcharshash, int comparestrhash, int i, int m)
//比較str從下標i開始和regex是否匹配上了,解決hash衝突的問題
private static boolean compare(char str, char regex, int i)
}return true;
}//start include
//end exclude
//已知主串上各個字元的hash值(charshash)
//返回start~end位置字串的hash值
static int hashhc(int hasharray, int start, int end)
return hash;
}static int hashhc(int charshash)
//計算出每個字元的hash值
static int hasharray(char str)
return charhash;
}//字元計算hash值的簡單實現
static int hc(char c)
}
字串匹配
題目描述 讀入資料string 然後讀入乙個短字串。要求查詢string 中和短字串的所有匹配,輸出行號 匹配字串。匹配時不區分大小寫,並且可以有乙個用中括號表示的模式匹配。如 aa 123 bb 就是說aa1bb aa2bb aa3bb都算匹配。輸入 輸入有多組資料。每組資料第一行輸入n 1 n ...
字串匹配
time limit 1000ms memory limit 65536k 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1,第二行代表string2,string1和string2中保證不出現...
字串匹配
面試題 給一串很長的字串,要求找到符合要求的字串,例如目的串 123 1 3 2 12 3 這些都要找出來 思路一 利用兩層迴圈,逐個查詢目的串中的字元,比如先查詢字元 1 是否在長字串中,再查詢 2 是否在長字串中,直到目的串遇到 0 是 include include include int m...