Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.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_Data Structures_Hashmap_In Memory - Fatal编程技术网

Java 寻找部分性质

Java 寻找部分性质,java,data-structures,hashmap,in-memory,Java,Data Structures,Hashmap,In Memory,我有一张地图。键包含6个字符串,属性类大致如下所示: public class Properties { private String propertyOne; private String propertyTwo; private String propertyThree; private String propertyFour; ... ... } 现在让我们假设我在地图中有一些条目,如下所示: 41111->{1,2,3,4,5} 4111

我有一张地图。键包含6个字符串,属性类大致如下所示:

public class Properties {
    private String propertyOne;
    private String propertyTwo;
    private String propertyThree;
    private String propertyFour;
    ...
    ...
}
现在让我们假设我在地图中有一些条目,如下所示:

41111->{1,2,3,4,5}

41112->{1,2,3,4,6}

41234->{1,2345,87,65}

51123->{1002003000000345123}

51122->{1002003000000556989}

现在,如果我执行
map.get(“12567”)
,我将获得所需的属性对象

我面临的挑战是,我必须创建一个能够保存部分数据的数据结构。通过部分数据,我的意思是如果我做了
map.get(“4111”)
我应该得到
{1,2,3,4,5}
(41111的属性)
{1,2,3,4,6}
(41112的属性)的交点,即
{1,2,3,4,null}。

类似地,
map.get(“41”)
应该产生
{1,2,null,null,null}

我现在有了一个解决方案,我创建了多个hashmap,其中包含所有可能的部分键及其对应的值,如:

Map``keyValuesForOneChar
包含所有可能的单个字符作为键及其对应的值

映射键值fortwochars
包含所有可能的两个字符作为键及其对应的值

我不喜欢这个解决方案,因为它非常简单,我不认为维护多个hashmap是一个好主意。还有一个问题是,我的原始数据计数约为200000,对于所有排列组合,我将创建大量的部分数据,而对于如此庞大的计数,我认为hashmaps的性能会降低。请为这个问题提出更好的解决方案。我有以下限制:

  • 解决方案应该严格地只在内存中使用
  • 查找速度应该更快。这就是为什么如果处理原始数据和准备数据结构需要额外的时间和内存,这应该不是问题
    HashMap绝对不是最适合您的问题的数据结构。由于键是字符串,因此可以实现trie(也称为前缀树)

    它的工作原理是将字符串键拆分为更小的字符串或字符。这样,您可以存储键的值,也可以存储常用前缀的值。也就是说,您可以将“41111”和“41112”的交集存储在公共前缀“4111”上。查找4111时,需要O(m)个步骤,其中m是键的长度,如果在trie中插入项时更新交点,则可以检索{1,2,3,4,5}和{1,2,3,4,6}的交点

    检索部分属性

    可以在构造trie时更新部分属性。假设您插入这对(41111,{1,2,3,4,5})。尝试是特定的树,它可以如下所示。符号
    k,v
    表示这是一个具有键
    k
    和值
    v
    的节点

    4,{1,2,3,4,5}
          |
    1,{1,2,3,4,5}
          |
    1,{1,2,3,4,5}
          |
    1,{1,2,3,4,5}
          |
    1,{1,2,3,4,5}
    
    在路径上的每个节点上,存储部分属性。现在,在插入该对(41112,{1,2,3,4,6})时,您将更新trie:

           4,{1,2,3,4,null}
                 |
           1,{1,2,3,4,null}
                 |
           1,{1,2,3,4,null}
                 |
           1,{1,2,3,4,null}
          /                \
    1,{1,2,3,4,5}     2,{1,2,3,4,6}
    
    同样,如果你插入41234,{1,2345,87,65},它将如下所示:

                  4,{1,2,null,null,null}
                             |
                  1,{1,2,null,null,null}
                 /                      \
           1,{1,2,3,4,null}          2,{1,2,345,87,65}
                 |                           |
           1,{1,2,3,4,null}          3,{1,2,345,87,65}
          /                \                 | 
    1,{1,2,3,4,5}     2,{1,2,3,4,6}  4,{1,2,345,87,65}
    

    执行此操作时,仅存储已插入项的公用前缀的部分属性,而不需要创建所有组合。另外,检索部分属性的算法与检索值的算法相同。

    完全同意。。现在我不必完成我的回答。Hashmap(任何映射实现)是完全错误的数据结构。感谢您的建议。但问题仍然在于获取部分属性。我仍然需要手动检查每一条记录并找到它。因此,方法是这样的:首先手动查找所有可能的部分数据,然后准备Trie。我添加了一个我所想到的示例,这比保留6个不同的HashMap并计算所有可能的组合和部分属性更有效。最后一个疑问。Trie的检索操作会比HashMap花费更多的时间吗?正如我所看到的,要获取任何键的属性,我必须从一个节点遍历到另一个节点,而HashMap只是一个基于索引的检索(前提是我的hash函数非常有效)。这是一个有趣的问题。根据我的经验,我将一个基本trie(未优化)与java的HashMap进行了基准测试,我的trie在put/get/delete随机序列上的效率比HashMap低几个百分点。(虽然钥匙的长度约为15-20个字符)。所以,我的答案是:我不知道,你需要对它进行基准测试才能得到答案。但是有了正确的实现,我相信您不会有疯狂的性能损失。通过一些优化,您很可能可以与HashMap竞争。对于@T.Clarverie answer,如果需要找到“11”作为键,然后它应该与41111、41112、51123和51122相交,或者搜索总是从键的开头开始?它应该总是从开头开始。