qwerty787788

Hashes!

Jul 17th, 2015
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.87 KB | None | 0 0
  1.     private class StringHash {
  2.         private int[] val1, val2;
  3.         private HashHelper helper;
  4.         String s;
  5.  
  6.         public StringHash(int[] val1, int[] val2, HashHelper helper, String s) {
  7.             super();
  8.             this.val1 = val1;
  9.             this.val2 = val2;
  10.             this.helper = helper;
  11.             this.s = s;
  12.         }
  13.  
  14.         public int getIntHash(int l, int r) {
  15.             if (r < l) {
  16.                 return 0;
  17.             }
  18.             long result = val1[r + 1] - val1[l] * 1L * helper.pow1[r - l + 1];
  19.             result %= helper.MOD1;
  20.             if (result < 0) {
  21.                 result += helper.MOD1;
  22.             }
  23.             return (int) result;
  24.         }
  25.  
  26.         public long getHashWithLength(int l, int r) {
  27.             if (r < l) {
  28.                 return 0;
  29.             }
  30.             return ((long) getIntHash(l, r) << 32) ^ (r - l + 1);
  31.         }
  32.  
  33.         public long getLongHash(int l, int r) {
  34.             if (r < l) {
  35.                 return 0;
  36.             }
  37.             long res;
  38.             {
  39.                 long result = val1[r + 1] - val1[l] * 1L
  40.                         * helper.pow1[r - l + 1];
  41.                 result %= helper.MOD1;
  42.                 if (result < 0) {
  43.                     result += helper.MOD1;
  44.                 }
  45.                 res = result;
  46.             }
  47.             {
  48.                 long result = val2[r + 1] - val2[l] * 1L
  49.                         * helper.pow2[r - l + 1];
  50.                 result %= helper.MOD2;
  51.                 if (result < 0) {
  52.                     result += helper.MOD2;
  53.                 }
  54.                 res = (res << 32) ^ result;
  55.             }
  56.             return res;
  57.         }
  58.     }
  59.  
  60.     private class HashHelper {
  61.         final Random rnd = new Random();
  62.         final int BILLION = (int) 1e9;
  63.         final int MUL = 239;
  64.         final int MOD1 = BigInteger
  65.                 .valueOf(BILLION + rnd.nextInt(BILLION / 10))
  66.                 .nextProbablePrime().intValue();
  67.         final int MOD2 = BigInteger
  68.                 .valueOf(BILLION + rnd.nextInt(BILLION / 10))
  69.                 .nextProbablePrime().intValue();
  70.         int[] pow1, pow2;
  71.  
  72.         public HashHelper(final int n) {
  73.             pow1 = new int[n];
  74.             pow2 = new int[n];
  75.             pow1[0] = pow2[0] = 1;
  76.             for (int i = 1; i < n; i++) {
  77.                 pow1[i] = (int) (pow1[i - 1] * 1L * MUL % MOD1);
  78.                 pow2[i] = (int) (pow2[i - 1] * 1L * MUL % MOD2);
  79.             }
  80.         }
  81.  
  82.         StringHash generateHash(String s) {
  83.             return new StringHash(generateIntHash(s, MOD1), generateIntHash(s,
  84.                     MOD2), this, s);
  85.         }
  86.  
  87.         public int compareInt(StringHash s1, int from1, int to1, StringHash s2,
  88.                 int from2, int to2) {
  89.             int len = Math.min(to1 - from1, to2 - from2) + 1;
  90.             int l = 0, r = len + 1;
  91.             while (r - l > 1) {
  92.                 int mid = (l + r) >>> 1;
  93.                 if (s1.getIntHash(from1, from1 + mid - 1) == s2.getIntHash(
  94.                         from2, from2 + mid - 1)) {
  95.                     l = mid;
  96.                 } else {
  97.                     r = mid;
  98.                 }
  99.             }
  100.             if (l == len) {
  101.                 if (to1 - from1 == to2 - from2) {
  102.                     return 0;
  103.                 }
  104.                 return (to1 - from1) - (to2 - from2);
  105.             }
  106.             return s1.s.charAt(from1 + l) - s2.s.charAt(from2 + l);
  107.         }
  108.  
  109.         long addHashWithLengths(long hash1, long hash2) {
  110.             int h1 = getHashFromHashWithLength(hash1), h2 = getHashFromHashWithLength(hash2);
  111.             int l1 = getLengthFromHashWithLength(hash1), l2 = getLengthFromHashWithLength(hash2);
  112.             int newHash = (int) ((h1 * 1L * pow1[l2] + h2) % MOD1);
  113.             return ((long) newHash << 32) ^ (l1 + l2);
  114.         }
  115.  
  116.         int getLengthFromHashWithLength(long hash) {
  117.             return (int) (hash & -1);
  118.         }
  119.  
  120.         int getHashFromHashWithLength(long hash) {
  121.             return (int) (hash >> 32);
  122.         }
  123.  
  124.         public int compareLong(StringHash s1, int from1, int to1,
  125.                 StringHash s2, int from2, int to2) {
  126.             int len = Math.min(to1 - from1, to2 - from2) + 1;
  127.             int l = 0, r = len + 1;
  128.             while (r - l > 1) {
  129.                 int mid = (l + r) >>> 1;
  130.                 if (s1.getLongHash(from1, from1 + mid - 1) == s2.getLongHash(
  131.                         from2, from2 + mid - 1)) {
  132.                     l = mid;
  133.                 } else {
  134.                     r = mid;
  135.                 }
  136.             }
  137.             if (l == len) {
  138.                 if (to1 - from1 == to2 - from2) {
  139.                     return 0;
  140.                 }
  141.                 return (to1 - from1) - (to2 - from2);
  142.             }
  143.             return s1.s.charAt(from1 + l) - s2.s.charAt(from2 + l);
  144.         }
  145.  
  146.         private int[] generateIntHash(String s, int MOD) {
  147.             int[] result = new int[s.length() + 1];
  148.             for (int i = 0; i < s.length(); i++) {
  149.                 result[i + 1] = (int) ((result[i] * 1L * MUL + s.charAt(i)) % MOD);
  150.             }
  151.             return result;
  152.         }
  153.     }
Advertisement
Add Comment
Please, Sign In to add comment