【问题标题】:searching the perfect data structure for storing and retrieving the elements [duplicate]搜索用于存储和检索元素的完美数据结构[重复]
【发布时间】:2015-06-14 13:45:36
【问题描述】:

我必须为我的需要选择一种数据结构,我正在解释以下值的条件

abc,def,rty,ytr,dft   which all are map to row R1B1 (actully key is combination of R1+B1)
abEERc,dFFFef,rGGty   which all are map to row R1B2 (actully key is combination of R1+B2)


  KEY                      VALUE
abc,def,rty,ytr,dft --->    R1B1
abEERc,dFFFef,rGGty --->    R1B2

现在,例如,假设我得到ytr,那么我将能够检索R1B1 或者,假设我得到了rGGty 的值,那么我就可以检索到R1B2

现在的情况是,问题在于搜索、复杂性和时间,因为事情必须按顺序进行

例如,它会首先选择第一行搜索ytr,它会先匹配abc,这将不匹配然后必须匹配def它不会再次匹配然后它会匹配rty 也不会匹配,然后它最终将与 ytr 匹配,最后它会找到密钥 R1B1 最终

类似地,如果需要搜索第二个字符串让我们说rGGty,那么它将扫描第一行,其中找不到该值,然后搜索将继续到第二行,并且在第三个元素的第二行中它会得到rGGty 作为元素,那么它将检索 R1B2 作为值

比方说,如果把这个东西放在 map 中,那么一个序列搜索就会在 key 上进行,然后只有我们才能找到对应的 value

请大家告诉我哪个是我可以在 java 中实现的最好的数据结构,我必须在非常快的时间内搜索键项以找到相应的值,这也不会影响性能 ,那种数据结构性能应该很高

如果有人可以建议我展示如何使用数字树来实现这一点,那也太好了

【问题讨论】:

  • 为什么不直接使用 HashMap?
  • 将字符串映射到值的哈希表和存储从值到字符串“集”的逆映射的哈希表。
  • @OliverCharlesworth 感谢您的建议,但仍然无法掌握请您详细解释一下,如果可能的话,一点代码可以帮助理解更多
  • @saadtaame 感谢您的建议,请您详细说明,以便我了解更多请提前谢谢
  • 你为什么要问两次完全相同的问题?

标签: java data-structures tree


【解决方案1】:

正如 cmets 建议的那样,您可以简单地使用 HashMap 或 HashTable,
如果您坚持自己实现结构,我建议使用搜索 trie。
在搜索 trie 中,需要的最大比较次数检索数据等于所用键的长度,因此要检索给定键(abc、def、rty、ytr、dft)的数据,需要进行 3 次比较
考虑以下维基百科链接:https://en.wikipedia.org/wiki/Trie
下面也是我快速而肮脏的搜索特里的实现(假设键是标准的 ASCII 字母):)-

public class DictionaryNode 
{
    DictionaryNode next[];
    String data;
    DictionaryNode()
    {
        next=new DictionaryNode[128];
        for(int i=0;i<next.length;i++)
        {
            next[i]=null;
        }
        data=null;
    }
}

public class Dictionary 
{
    DictionaryNode root;
    Dictionary()
    {
        root = new DictionaryNode();
    }
    public boolean add(String key,String data)
    {
        char[]ch=key.toCharArray();
        DictionaryNode current=root;
        for(int i=0;i<ch.length;i++)
        {
            if(current.next[ch[0]]==null)
            {
                current.next[ch[0]]=new DictionaryNode();
            }
            current=current.next[ch[0]];
        }
        if(current.data==null)
        {
            current.data=data;
            return true;
        }
        else
        {
            return false;
        }
    }
    public String search(String key)
    {
        char[]ch=key.toCharArray();
        DictionaryNode current=root;
        for(int i=0;i<ch.length;i++)
        {
            if(current.next[ch[0]]==null)
            {
                return null;
            }
            else
            {
                current=current.next[ch[0]];
            }
        }
        return current.data;
    }
}

public class main {
    public static void main(String []args)
    {
        Dictionary d=new Dictionary();
        d.add("abc", "R1B1");
        d.add("def", "R1B1");
        d.add("rty", "R1B1");
        d.add("ytr", "R1B1");
        d.add("dft", "R1B1");
        System.out.println(d.search("abc"));
        System.out.println(d.search("ab"));
    }
}

【讨论】:

  • 非常感谢,请您详细解释一下上面的代码是如何工作的,这将有助于更多的锉刀谢谢
  • 还请解释一下,如前所述,在搜索尝试中,检索数据所需的最大比较次数等于所用密钥的长度,所以假设我将密钥长度为 6 的情况一个密钥长度是 10 那么它会影响性能
  • @eretg ghg 搜索树是一种数据结构,树中的每个节点都可以说是键中的一个字符,请看一下维基百科的文章,应该更好地解释结构比我在评论中所能做到的,同样关于密钥长度为 6 或 10 的点,如果您的密钥很少,它确实会影响性能,但是考虑密钥长度为 10,我们可以在 62 次比较中检索 10 次比较中的任何密钥 ^ 10个可能的钥匙!!如果您的密钥比使用哪种算法都少,那么您将获得相似的性能,例如(线性搜索或二进制搜索)
  • 非常感谢您为我发布的上述结构,但仍然会有我要放入的密钥非常长,说少数密钥的长度为 4chars将是几个 10 字符长度的键,所以如果混合键长度会出现这种情况,所以在这种情况下会影响性能谢谢 inadvance
  • 应该没有任何影响,(长度为 4 的键需要进行 4 次比较才能检索,而长度为 10 的键需要进行 10 次比较才能检索)较长的键在内存方面会产生较小的开销,因为需要更多的中间节点,但除非你有内存限制,否则它不应该是一个重要的限制。
【解决方案2】:

在您的情况下反转键和值并使用 Multimap 数据结构。在此处查看有关Multimap 的好文章。 http://tomjefferys.blogspot.com/2011/09/multimaps-google-guava.html

@Test
public void getColor(){
    Multimap<String,String> myMultimap = ArrayListMultimap.create();


    myMultimap.put("R1B1","abc");
    myMultimap.put("R1B2","def");

    myMultimap.put("R1B2","abEERc");
    myMultimap.put("R1B2","rGGty");

    Multimap<String, String> invertedMultimap = Multimaps.invertFrom(myMultimap, ArrayListMultimap.<String, String>create());

    System.out.println(invertedMultimap.get("abc"));

}

【讨论】:

  • 谢谢你能告诉我这对我上面的问题陈述有什么帮助吗?请你发布有助于掌握我的代码
  • 你能解释一下上面程序中发生了什么,特别是invertedMultimap的上下文,特别是invertFrom部分发生了什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
相关资源
最近更新 更多