rk字符串匹配算法java實現

 

 

/**
 * rk字符串匹配算法,主要引入了hash的概念,
 * 利用子串的hash值依次對比主串相應長度的子串hash值
 * 並對hash值相同的子串進行匹配對比
 */
public class RKSearch {

    /**
     * rk算法入口
     * @param t 主字符串
     * @param p 子字符串
     * @return
     */
    public int rk(String t,String p){
        // 字符串非法判定
        if (t == null||t.length() == 0 || p == null || p.length() == 0 || p.length() > t.length()){
            return -1;
        }
        // 計算子串hash值
        int hash = hash(p,26,31,0,p.length());
        for (int i = 0;i< t.length();i++){
            // 對主串內的數字一次進行hash計算,並對比子串是否匹配
            if (hash(t,26,31,i,p.length()) == hash && match(t,p,i)){
                return i;
            }
        }
        return -1;
    }

    /**
     * 自定義hash算法
     * @param str
     * @param r 進制數
     * @param k 將字符串映射到k的範圍
     * @param start 從str串的開始位置
     * @param len 子串的長度
     * @return
     */
    private int hash(String str,int r,int k,int start,int len){
        int hash = 0; // 設定hash值爲0
        /**
         * 對字符串內的每個字符串進行計算
         */
        for (int i = start;i<start+len;i++){
            // 進制係數 與 hash 的積 + 每個字符與範圍取餘的結果
            hash = (r * hash + str.charAt(i) % k);
        }
        // 將最後的結果,映射到指定範圍內
        return hash % k;
    }

    /**
     * 對於hash計算結果相同的兩個子串,是否匹配的比較
     * 主要判定hash衝突情況下的匹配問題
     * @param t 主串
     * @param p 子串
     * @param i 從主串下標爲i的地方開始比較
     * @return
     */
    private boolean match(String t,String p,int i){
        for (int j = 0 ; j < p.length();j++){
            if (p.charAt(j) != t.charAt(j + i)){
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String test = "adbsasdfddddsasdffesase";
        String sub = "sd";
        RKSearch rkSearch = new RKSearch();
        int rk = rkSearch.rk(test, sub);
        System.out.println(rk);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章