设计电话簿的数据结构

时间:2011-06-26 07:01:43

标签: algorithm data-structures

设计电话簿的数据结构,用于存储姓名和电话号码,以便我们可以搜索关键字给定名称,反之亦然。

我们可以使用以下两个哈希映射

Map<String,int>
Map<int,String>

但它需要两倍的内存。任何人都可以建议任何其他解决方案吗?

4 个答案:

答案 0 :(得分:1)

  

bimap(或“双向地图”)是一个   保留唯一性的地图   它的价值以及它的价值   键。此约束启用了bimaps   支持“逆视图”,即   另一个含有相同的bimap   作为这个bimap的条目,但有   反转键和值。

http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html

BiMap<String, Integer> biMap = HashBiMap.create();

biMap.put("Mike", 123);
biMap.put("John", 456);
biMap.put("Steven", 789);

BiMap<Integer, String> invertedBiMap = biMap.inverse();

修改: Multimaps

Multimap<String, String> multimap = HashMultimap.create();
multimap.put("John", "111111111");
multimap.put("John", "222222222");
multimap.put("Mike", "333333333");

System.out.println(multimap.get("John")); //[222222222, 111111111]

for(Map.Entry<String, String> entry : multimap.entries()){
    if(entry.getValue().equals("222222222")){
        System.out.println(entry.getKey()); //John
    }
}
//or

Multimap<String, String> inverted = HashMultimap.create();
Multimaps.invertFrom(multimap, inverted);
System.out.println(inverted.get("222222222")); //[John]

答案 1 :(得分:1)

一个人可以拥有多个号码,一个号码可以属于多个人(一个家庭成员)。正如尼克所说,一般情况下,电话号码可以包含非数字字符。所有考虑,而不是Map<String,int>您可能正在使用Map<String,List<String>>,或只有指向字符串的指针(用C ++术语),以避免冗余:Map<String*,List<String*>>

答案 2 :(得分:0)

另一种可能性是将字符串存储在trie中,并且有一个'$'符号表示每个字符串的结尾。为每个步骤使用双向链接指针,并从每个'$'(名称末尾)到其数字(在数组或列表中)保存双链接指针。

现在,当您想从名称中获取电话时:

find the '$' indicating the end of the word for this string.
it is connected to a number in a list - that is your number.

如果您想从手机获取姓名:

find the number, it is connected to a '$' sign.
follow the up-links all the way to the root, this will get you the name (reversed). 
reverse it and you are done.

另外,正如我在评论中所说的那样(关于双映射方法):假​​设你的字符串非常大,并且映射包含指向字符串的指针/引用(而不是实际的字符串),你可以假设存储所需的空间不会是双倍的,而是更好的。

答案 3 :(得分:-1)

使用二叉搜索树来实现电话目录是最好的方法。想想手机电话联系人列表的实际实施情况。它按字母顺序排序。如果使用地图模板,那么我们将不会得到排序列表。您无法对地图的元素进行排序,但效果不佳。

唯一的方法是二叉树方式。因为,在添加新条目时,它以有序的方式插入。因此,不再需要排序。它已经订购了。请记住,left_tree&lt; root和root&lt;在二叉树的情况下right_tree。