假设我有名单。
ArrayList<String> nameslist = new ArrayList<String>();
nameslist.add("jon");
nameslist.add("david");
nameslist.add("davis");
nameslist.add("jonson");
此列表中包含数千个名单。知道这个列表包含以给定名称开头的名称的方法是什么。
String name = "jon"
结果应为2.
我试过将list的每个元素与substring函数进行比较(它可以工作但是)当列表很大时,它非常慢。
谢谢你的到来。
答案 0 :(得分:7)
您可以使用TreeSet进行O(log n)访问,并编写如下内容:
TreeSet<String> set = new TreeSet<String>();
set.add("jon");
set.add("david");
set.add("davis");
set.add("jonson");
set.add("henry");
Set<String> subset = set.tailSet("jon");
int count = 0;
for (String s : subset) {
if (s.startsWith("jon")) count++;
else break;
}
System.out.println("count = " + count);
按预期打印2个。
或者,您可以使用Set<String> subset = set.subSet("jon", "joo");
返回以"jon"
开头的完整名称列表,但是您需要在jons之后提供第一个无效条目(在这种情况下:“joo” “)。
答案 1 :(得分:2)
看看Trie。它是一种旨在根据字前缀执行快速搜索的数据结构。您可能需要稍微操作它以获取子树中的叶子数,但无论如何您都不会遍历整个列表。
答案 2 :(得分:1)
在ArrayList
(或线性数组)中搜索的复杂性为O(n)
,其中n
是数组中元素的数量。
为获得最佳效果,您可以看到Trie
答案 3 :(得分:0)
对每个元素的ArrayList
进行迭代,检查它是否以jon
开头。时间复杂度为O(n)。
答案 4 :(得分:0)
您需要迭代每个名称并在其中找到名称。
String name = "jon";
int count=0;
for(String n:nameslist){
if(n.contains(name){
count++;
}
}
答案 5 :(得分:0)
“非常慢”究竟是什么意思?
实际上,唯一的方法是遍历列表并检查每个元素:
int count = 0;
for (String name : nameslist) {
if (name.startsWith("jon")) {
count++;
}
}
System.out.println("Found: " + count);
答案 6 :(得分:0)
如果列表中的字符串不是太长,你可以使用这个作弊:在HashSet中存储所有前缀,你的复杂性将是~O(1):
// Preprocessing
List<String> list = Arrays.asList("hello", "world"); // Your list
Set<String> set = new HashSet<>()
for(String s: list) {
for (int i = 1; i <= s.length; i++) {
set.add(s.substring(0, i));
}
}
// Now you want to test
assert true == set.contains("wor")
如果不是,您可以使用任何全文搜索引擎,例如Apache Lucene
答案 7 :(得分:0)
我建议您创建一个Runnable来处理列表元素。然后创建一个具有固定池大小的ExecutorService,它同时处理元素。
粗略的例子:
ExecutorService executor = Executors.newFixedThreadPool(5);
for (String str : coll){
Runnable r = new StringProcessor(str);
executor.execute(r);
}
答案 8 :(得分:0)
我建议使用TreeSet。
以类似方式访问每个元素并增加计数。算术上你可以改善表现。
int count = 0;
iter = list.iterator();
String name;
while(iter.hasNext()) {
name = iter.next();
if (name.startsWith("jon")) {
count++;
}
if(name.startsWith("k")) break;
}
这个中断消除了对其余字符串比较的检查。
答案 9 :(得分:0)
您可以考虑Boyer–Moore string search algorithm。 复杂性O(n + m)最坏的情况。