Advertisement
sweet1cris

Untitled

Sep 21st, 2017
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.49 KB | None | 0 0
  1. // Notice:
  2. // 1. There is no assumption about the charset used in the String,
  3. //    so that we can not assume we are using 26 lower case characters.
  4. // 2. This is the most correct version of RabinKarp in computer programming,
  5. //    we need to handle 1. we could use arbitrary charset, 2. the overflow case,
  6. //    by taking the module operation on a very large number.
  7. // 3. You probably do not need to write this kind of solution to handle above
  8. //    two cases, if you are in an interview. But it is still necessary to
  9. //    understand the reason behind it.
  10. public class Strstr {
  11.   // Method 1: Naive solution.
  12.   public int strstrI(String large, String small) {
  13.     if (large.length() < small.length()) {
  14.       return -1;
  15.     }
  16.     // return 0 if small is empty.
  17.     if (small.length() == 0) {
  18.       return 0;
  19.     }
  20.     for (int i = 0; i <= large.length() - small.length(); i++) {
  21.       if (equals(large, i, small)) {
  22.         return i;
  23.       }
  24.     }
  25.     return -1;
  26.   }
  27.  
  28.   // Method 2: RabinKarp
  29.   public int strstrII(String large, String small) {
  30.     if (large.length() < small.length()) {
  31.       return -1;
  32.     }
  33.     // return 0 if small is empty.
  34.     if (small.length() == 0) {
  35.       return 0;
  36.     }
  37.     // We need a large prime as module end.
  38.     int largePrime = 101;
  39.     // We also need a small prime to calculate the hash value
  40.     // (since the charset would be very large, e.g. 1,112,064 for using UTF,
  41.     // we can not use that number).
  42.     int prime = 31;
  43.     int seed = 1;
  44.     // hash value is calculated using the smallPrime and taken the module
  45.     // operation on largePrime.
  46.     // hash = (s0*smallP^k + s1*smallP^(k-1) + ... + sk*smallP^0) % largeP
  47.     int targetHash = small.charAt(0) % largePrime;
  48.     for (int i = 1; i < small.length(); i++) {
  49.       seed = moduleHash(seed, 0, prime, largePrime);
  50.       targetHash = moduleHash(targetHash, small.charAt(i), prime, largePrime);
  51.     }
  52.     int hash = 0;
  53.     for (int i = 0; i < small.length(); i++) {
  54.       hash = moduleHash(hash, large.charAt(i), prime, largePrime);
  55.     }
  56.     if (hash == targetHash && equals(large, 0, small)) {
  57.       return 0;
  58.     }
  59.     for (int i = 1; i <= large.length() - small.length(); i++) {
  60.       // we need to make sure the module number is non-negative.
  61.       hash = nonNegative(hash - seed * large.charAt(i - 1) % largePrime,
  62. largePrime);
  63.       hash = moduleHash(hash, large.charAt(i + small.length() - 1), prime,
  64. largePrime);
  65.       // Notice: If the hash matches, it does not mean we really find a
  66.       // substring match.
  67.       // Because there is collision, we need to check if the substring really
  68.       // matches the small string.
  69.       // On average, this will not increase the time complexity, the probability
  70.       // of collision is O(1) so we still have O(N + M).
  71.       if (hash == targetHash && equals(large, i, small)) {
  72.         return i;
  73.       }
  74.     }
  75.     return -1;
  76.   }
  77.  
  78.   public boolean equals(String large, int start, String small) {
  79.     for (int i = 0; i < small.length(); i++) {
  80.       if (large.charAt(i + start) != small.charAt(i)) {
  81.         return false;
  82.       }
  83.     }
  84.     return true;
  85.   }
  86.  
  87.   public int moduleHash(int hash, int addition, int prime, int largePrime) {
  88.     return (hash * prime % largePrime + addition) % largePrime;
  89.   }
  90.  
  91.   public int nonNegative(int hash, int largePrime) {
  92.     if (hash < 0) {
  93.       hash += largePrime;
  94.     }
  95.     return hash;
  96.   }
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement