[英]Best way to perfectly hash a three letter lowercase String in Java?
我當前的解決方案使用多維數組,是否存在更簡單的解決方案? 我想在O(1)時間內訪問散列對象,並希望充分利用內存空間,因此需要完美的散列。
public final class PerfectHash {
private Object[][][] hashtable = new Object[26][26][26];
public void storeObjectAgainst3letterStringKey(Object o, String s){
int[] coord = stringToCoord(s);
hashtable[coord[0]][coord[1]][coord[2]] = o;
}
public Object get(String s){
int[] coord = stringToCoord(s);
return hashtable[coord[0]][coord[1]][coord[2]];
}
private int[] stringToCoord(String s){
if (!s.matches("[a-z][a-z][a-z]")){
throw new IllegalStateException("invalid input, expecting 3 alphabet letters");
}
// 1-26
// 1-26
// 1-26
String lowercase = s.toLowerCase();
// 97-122 integers for lower case ascii
int[] coord = new int[3];
for (int i=0;i<lowercase.length();++i){
int ascii = (int)lowercase.charAt(i);
int alpha = ascii - 97; // 0-25
coord[i] = alpha;
}
return coord;
}
}
您甚至不需要先轉換String。 如果您的三個字符是小寫字母,則可以執行此操作。
public static int hashFor(String s) {
assert s.length() == 3 && isLower(s.charAt(0)) && isLower(s.charAt(1)) && isLower(s.charAt(2));
return ((s.charAt(0) - 'a') * 26 + s.charAt(1) - 'a') * 26 + s.charAt(2) - 'a';
}
// check a-z not all lowercase letters.
public static boolean isLower(char ch) {
return ch >= 'a' && ch <= 'z';
}
更優化的版本是
public static int hashFor(String s) {
return s.charAt(0) * (26 * 26) + s.charAt(1) * 26 + s.charAt(2) - ('a' * (26*26+26+1));
}
只有數字的計算將由編譯器優化。
順便說一句,使用matches()可能比其他所有方法慢100倍。 ;)
如果已經確定必須使用小寫字母,則無需轉換為小寫字母。
您可以只使用一維數組而不是3維數組。
然后添加一個功能
public Object get(String s){
int[] coord = stringToCoord(s);
int hashindex = (coord[0]*26 + coord[1])*26 + coord[2];
return hashtable[hashindex];
}
此外,查看特里數據結構,它們對於有效的字符串查找很有用。
唯一可能更有效的方法是,將您的字符串直接映射到單個哈希值,並在一維數組中進行查找:
public final class PerfectHash {
private Object[] hashtable = new Object[26*26*26];
private int getHash(String s) {
char a = s.charAt(0) - 'a', b = s.charAt(1) - 'a', c = s.charAt(2) - 'a';
if(s.length() != 3 || a >= 26 || b >= 26 || c >= 26)
throw new IllegalStateException("invalid input, expecting 3 alphabet letters");
return (a*26+b)*26+c;
}
public object get(String s) {return hashtable[getHash(s)];}
public void set(String s, Object o) {hashtable[getHash(s)] = o;}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.