zoukankan      html  css  js  c++  java
  • lintcode594

    Implement strStr function in O(n + m) time.
    strStr return the first index of the target string in a source string. The length of the target string is m and the length of the source string is n.
    If target does not exist in source, just return -1.
    Example
    Given source = abcdef, target = bcd, return 1.
     
    Rabin Karp Algorithm。用Hash方程的思想做。自己实现Hash function。
    1.提前算好target的code。
    2.开始读入source的每个字符,在for循环里计算所有长度为target.length()的子字符串的hashcode。
    3.对比,如果code一样,要进一步对比是否substring的确一样以排除false positive.
     
    细节:
    1.第二步内比如从abc -> bcd,for循环每次都加了新的字符,d已经被加上去了,你只要轻松地排除窗口刚滑走的a*幂次即可。因为幂次固定是31*target.length(),可以提早把幂次算好。
    2.对%BASE这个操作每次计算别忘了。
    3.对两个各自对BASE取余过的数做减法后,可能会出来负数,这时候不好 
     
    我的实现:
    public class Solution {
        /*
         * @param source: A source string
         * @param target: A target string
         * @return: An integer as index
         */
        public int strStr2(String source, String target) {
            // write your code here
            if (source == null || target == null) {
                return -1;
            }
            if (target.length() == 0) {
                return 0;
            }
            
            int BASE = 100000;
            int length = target.length();
            
            // 31^length, 31 is HASHBASE.
            int power = 1;
            for (int i = 0; i < length; i++) {
                power = (power * 31) % BASE;
            }
            
            int targetCode = 0;
            for (int i = 0; i < length; i++) {
                targetCode = (targetCode * 31 + target.charAt(i)) % BASE;
            }
            
            int sourceCode = 0;
            for (int i = 0; i < source.length(); i++) {
                sourceCode = (sourceCode * 31 + source.charAt(i)) % BASE;
                
                if (i >= length) {
                    //注意这里。可能出现负数的地方不要直接再%,用if处理。
                    sourceCode = sourceCode - (source.charAt(i - length) * power) % BASE;
                    if (sourceCode < 0) {
                        sourceCode += BASE;
                    }
                }
                
                if (i >= length - 1 && sourceCode == targetCode 
                    && source.substring(i - length + 1, i + 1).equals(target)) {
                    return i - length + 1;    
                }
            }
            
            return -1;
        }
    }

    九章实现:

    public class Solution {
        /**
         * @param source a source string
         * @param target a target string
         * @return an integer as index
         */
        public int strStr2(String source, String target) {
            if(target == null) {
                return -1;
            }
            int m = target.length();
            if(m == 0 && source != null) {
                return 0;
            }
            
            if(source == null) {
                return -1;
            }
            int n = source.length();
            if(n == 0) {
                return -1;
            }
    
            // mod could be any big integer
            // just make sure mod * 33 wont exceed max value of int.
            int mod = Integer.MAX_VALUE / 33;
            int hash_target = 0;
    
            // 33 could be something else like 26 or whatever you want
            for (int i = 0; i < m; ++i) {
                hash_target = (hash_target * 33 + target.charAt(i) - 'a') % mod;
                if (hash_target < 0) {
                    hash_target += mod;
                }
            }
    
            int m33 = 1;
            for (int i = 0; i < m - 1; ++i) {
                m33 = m33 * 33 % mod;
            }
    
            int value = 0;
            for (int i = 0; i < n; ++i) {
                if (i >= m) {
                    value = (value - m33 * (source.charAt(i - m) - 'a')) % mod;
                }
    
                value = (value * 33 + source.charAt(i) - 'a') % mod;
                if (value < 0) {
                    value += mod;
                }
    
                if (i >= m - 1 && value == hash_target) {
                    // you have to double check by directly compare the string
                    if (target.equals(source.substring(i - m + 1, i + 1))) {
                        return i - m + 1;
                    }
                }
            }
            return -1;
        }
    }
  • 相关阅读:
    Java并发(五):并发,迭代器和容器
    Java并发(四):并发集合ConcurrentHashMap的源码分析
    Java爬虫初体验
    提升Java代码质量(三)
    Get和Post的初步探究
    01-什么是ElasticSearch
    python-实现动态web服务器
    python-实现二叉树
    python-实现栈结构
    python-实现单链表
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9429780.html
Copyright © 2011-2022 走看看