Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 散列三个整数集的最佳方法_Java_Optimization_Data Structures_Hashmap_Tuples - Fatal编程技术网

Java 散列三个整数集的最佳方法

Java 散列三个整数集的最佳方法,java,optimization,data-structures,hashmap,tuples,Java,Optimization,Data Structures,Hashmap,Tuples,我正在尝试编写一个程序,可以快速找到所有与通配符和已知字母匹配的字符串。例如,L*G将返回LOG、LAG、LEG。我正在寻找一些可以让我快速查找的东西,但我不在乎首先创建树所需的时间 我的想法是将“三元组”映射到字符串的ArrayList的Hashmap:基本上,是符合某个索引、该索引处的字符和长度标准的所有字符串的列表 但我现在的问题是为这些“三元组”生成一个好的哈希函数,这样每个三元组都是唯一的 这是我现在的代码 import java.util.ArrayList; import java

我正在尝试编写一个程序,可以快速找到所有与通配符和已知字母匹配的字符串。例如,L*G将返回LOG、LAG、LEG。我正在寻找一些可以让我快速查找的东西,但我不在乎首先创建树所需的时间

我的想法是将“三元组”映射到字符串的ArrayList的Hashmap:基本上,是符合某个索引、该索引处的字符和长度标准的所有字符串的列表

但我现在的问题是为这些“三元组”生成一个好的哈希函数,这样每个三元组都是唯一的

这是我现在的代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class CWSolutionT {
HashMap<Triple, ArrayList<String>> tripleMap = new HashMap<Triple, ArrayList<String>>();

public CWSolutionT(List<String> allWords) {
    for (String word : allWords) {
        for (int letter = 0; letter < word.length(); letter++) {
            ArrayList<String> tempList = new ArrayList<String>();
            Triple key = new Triple(letter, word.charAt(letter),
                    word.length());
            if (tripleMap.get(key) == null) {
                tempList.add(word);
                tripleMap.put(key, tempList);
            } else {
                tempList = tripleMap.get(key);
                tempList.add(word);
                tripleMap.put(key, tempList);
            }
        }
    }
}

public List<String> solutions(String pattern, int maxRequired) {
    List<String> sol = new ArrayList<String>();
    List<List<String>> solList = new ArrayList<List<String>>();
    int length = pattern.length();
    for (int i = 0; i < length; i++) {
        if (pattern.charAt(i) != '*') {
            Triple key = new Triple(i, pattern.charAt(i), pattern.length());
            solList.add(tripleMap.get(key));
        }
    }
    if (solList.size() == 0) {
        // implement later
    }

    if (solList.size() == 1)
        return solList.get(0);

    for (List<String> list : solList) {
        sol.retainAll(list);
    }
    return sol;
}

private class Triple {
    public final int index;
    public final char letter;
    public final int length;

    public Triple(int ind, char let, int len) {
        index = ind;
        letter = let;
        length = len;
    }

    public boolean equals(Object o) {
        if (o == null)
            return false;
        if (o == this)
            return true;
        if (!(o instanceof Triple)) {
            return false;
        }
        Triple comp = (Triple) o;
        if (this.hashCode() == comp.hashCode())
            return true;
        return false;
    }

    public String toString() {
        return "(" + index + ", " + letter + ", " + length + ")";
    }

    public int hashCode() {
        return (int) (.5 * (index + letter + length)
                * (index + letter + length + 1) + letter + length);
    }
}
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
公共类CWT解决方案{
HashMap tripleMap=新HashMap();
公共CWSolutionT(列出所有单词){
for(字符串字:allWords){
for(int-letter=0;letter
您必须在
元组中超越

您必须在
元组中超越

HashMap需要实现
equals
hashCode
,并且您没有超越它们。现在,地图基本上只检查对象标识(someOldObject==someNewObject)


看起来您试图实现equals方法,但签名是错误的,
Object#equals
对象
作为参数,而您的方法将
元组
作为参数,因此它被重载。这个问题的答案有一些实现equals和hashCode的技巧:。

HashMap需要实现
equals
hashCode
,并且您没有覆盖它们。现在,地图基本上只检查对象标识(someOldObject==someNewObject)


看起来您试图实现equals方法,但签名是错误的,
Object#equals
对象
作为参数,而您的方法将
元组
作为参数,因此它被重载。这个问题的答案有一些实现equals和hashCode的技巧:。

一般来说,不可能将两个
int
压缩成一个。康托配对函数适用于无限域,但将其转移到
int
s将毫无意义

您的输入是一个三元组
(int,char,int)
,理论上考虑了
2**32*2**16*2**32=2**80
的可能性,显然不能内射映射到只包含
2**32
元素的集合

借助有关输入值的一些知识,您可以做得更好,但可能还不够好。例如,您知道
索引
长度
都是非负的,这使您的域小了四倍。。。但那没什么

如果您知道
索引
长度
都小于256,则可以通过

public int hashCode() {
    return index + 256 * length + 256 * 256 * letter;
}
此表达式可以更高效地编写为

index + (length << 8) + (letter << 16)

太糟糕了。。。。你使用的是三件东西的配对!元组
(0,'A',1)
(0,'B',0)
具有相同的
hashCode
,因此
等于
返回true。实际上,您是Cantor配对
索引
字母+长度
,而您必须使用两个配对。

一般来说,不可能将两个
int
压缩为一个配对。康托配对函数适用于无限域,但将其转移到
int
s将毫无意义

您的输入是一个三元组
(int,char,int)
,理论上考虑了
2**32*2**16*2**32=2**80
的可能性,显然不能内射映射到只包含
2**32
元素的集合

借助有关输入值的一些知识,您可以做得更好,但可能还不够好。例如,您知道
索引
长度
都是非负的,这使您的域成为四个ti
public int hashCode() {
    return (int) (.5 * (index + letter + length)
            * (index + letter + length + 1) + letter + length);
}