面试难题

时间:2015-04-14 20:54:22

标签: java algorithm

编写Java代码以查找仅包含来自以下字母的9个字母的字符串:     acegikmnoprstuvy

字符串散列产生的地方:     932246728227799

如果散列函数由以下伪代码定义:

hash (String s) { 
    h = 7 
    letters = "acegikmnoprstuvy" 
    for(i = 0; i < s.length; i++) { 
        h = (h * 37 + letters.indexOf(s[i])) 
    } 
    return h 
} 

例如,如果我们试图找到生成字符串690336378753的7字母字符串,答案就是&#34;报告&#34;。

4 个答案:

答案 0 :(得分:3)

哈希基本上对从基数为37到基数10的字符串进行编码。为了反转哈希,我们将从基数10转换为基数37.当我们处理它时,不妨查找字符。

public class Hashcode {
  static final String ALPHABET = "acegikmnoprstuvy";

  public static long hash(String s) {
    long h = 7;
    for (int i=0; i<s.length(); i++) {
      h = (h * 37 + ALPHABET.indexOf(s.charAt(i)));
    }
    return h;
  }

  public static String unhash(long n) {
    String result = "";
    while (n>7) {
      result = ALPHABET.charAt((int)(n%37)) + result;
      n = n/37;
    }
    if (n != 7) {
      System.err.println("Error, hash parity incorrect.");
      System.exit(1);
    }
    return result;
  }

  public static void main(String[] args) {
    System.out.println(hash("reports"));
    System.out.println(unhash(690336378753L));
    System.out.println(unhash(932246728227799L));
    System.out.println(hash("mymitsapp"));
  }
}

答案 1 :(得分:3)

以数学方式查看函数的作用。

当你进入for循环时,你从h = 7开始。 for循环遍历单词中的字母。每次迭代都会更新h:h = h * 37 + next_letter

所以尝试选择一个词,ex&#34; ADD&#34;。
循环1:h = 7 * 37 + "A"
循环2:h = (7 * 37 + "A") * 37 + "D"7 * 37^2 + "A" * 37 + "D"
循环3:h = (7 * 37^2 + "A" * 37 + "D") * 37 + D7 * 37^3 + "A" * 37^2 + "D" * 37 + "D"

所以你的哈希将是7 * 37^3 + "A" * 37^2 + "D" * 37 + "D"

在实际情况下,字母会转换为索引编号,因为最大索引小于37,您只能得到一个可能的解决方案。将哈希值重写为7 * 37^3 + "A" * 37^2 + "D" * 37 + "D"也会显示它可以作为7 "A" "D" "D"在基数37中写得清楚。

长答案简短:只需将其转换为基础37并删除前导7.

答案 2 :(得分:1)

基本上,你最终会解决这个问题:     word(hashcode,len) = let w: hash(w) = hashcode 或者有更具体的功能:

word(hashcode,len) = let w: for(i = 0 , i < len , 1){w[len-i-1] * 37^i} + 909732178565539 - hashcode = 0

所以现在我们有了一个等式,下一步是解决它: 将(hashcode-909732178565539)从十进制转换为基数37.在带有基数37的数字中,每个数字将代表您单词中的一个字符。现在您需要做的就是将单个数字转换为您的字符。

答案 3 :(得分:1)

这是用php编写的解决方案。您需要做的就是在基数37中取消给定的整数。

function unhash($h) {  
    $letters = "acegikmnoprstuvy";
    //new string return 
    $s='';
    while ($h>7){
        //hold
        $pos = fmod($h, 37);
        $s = $letters[$pos].$s;
        $h = ($h-$pos) / 37 ;
    }
    return $s;
}