我有一个包含17,000个单词的ArrayList。我只需要在列表中添加一个单词,如果它还没有,我需要保留列表的排序顺序。即,我需要将其放入字母顺序正确的位置。
我不知道如何找到插入它的正确位置。 我正在使用二进制搜索来查找该单词是否已经在列表中,如果它在那里则返回索引,如果不是则返回-1。 我打算使用ArrayList.add(int index,E element)将它放入。
答案 0 :(得分:3)
将ArrayList
转换为TreeSet
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html
TreeSet
将为您处理重复项,并按字母顺序保留字词。
示例:(WordList
是单词ArrayList
)
TreeSet<String> WordSet = new TreeSet<String>(WordList);
答案 1 :(得分:2)
使用内置的binarySearch
方法。如果找不到密钥,则返回的号码为
-(insertionIndex) - 1
答案 2 :(得分:1)
binary search浮现在脑海中,列表api可能包含更好的
在二进制搜索中,您将到达剩下2个项目的位置,一个位于上方,一个位于下方,其中一个可能==指向您的项目。对于您的情况,您将没有==大小写,因此返回较高的索引并插入其位置。我不知道java是否有元组类,或者你可以构建一个容器。无论哪种方式,返回类似的东西:
(bool, int) binSearch(IList list)
returns true, -1 if found
returns false, higher of 2 bounds otherwise
显然这不是java,但它不是转换的延伸
答案 3 :(得分:1)
如果您编写了二进制搜索,则可以对其进行修改以返回搜索到的最后一个值。该值可以是匹配字符串的位置,也可以是应插入的位置。
这是在二进制搜索中,您将细分列表,直到您找到该字符串或无法进一步细分它。您无法再细分列表的位置是应插入字符串的位置。
答案 4 :(得分:0)
为了强化一个过程,我们都会想到一般的想法就是使用更多的内存。这里,它可以是每个字母的第一个字符串的索引。例如,另一个ArrayList,用伪写:
ArrayList indexes;
indexes[0] = {"a", 0};
indexes[1] = {"b", 123};
...
对于以“a”开头的字符串,您可以在索引0-123之间进行二进制搜索。
答案 5 :(得分:0)
如果没有重复的话,正如您所说,您可以考虑实施trie。对trie的插入操作比哈希表中的插入操作要快一些,因为没有冲突。搜索也是如此。
此外,在ArrayList
中,在列表中间插入一个元素,这意味着重新定位一半元素或增加数组大小,这可能有些昂贵。
如果您感到好奇,可以在以下页面中看到实施:https://forums.oracle.com/forums/thread.jspa?messageID=8787521