在JAVA中查找子字符串的最快方法

在JAVA中查找子字符串的最快方法,java,performance,arraylist,substring,Java,Performance,Arraylist,Substring,假设我有一张名单 ArrayList<String> nameslist = new ArrayList<String>(); nameslist.add("jon"); nameslist.add("david"); nameslist.add("davis"); nameslist.add("jonson"); 结果应该是2 我尝试过用子字符串函数比较列表中的每个元素(它可以工作,但速度非常慢,特别是当列表很大时) 感谢是前进。在数组列表上迭代,检查每个元素是否以j

假设我有一张名单

ArrayList<String> nameslist = new ArrayList<String>();
nameslist.add("jon");
nameslist.add("david");
nameslist.add("davis");
nameslist.add("jonson");
结果应该是2

我尝试过用子字符串函数比较列表中的每个元素(它可以工作,但速度非常慢,特别是当列表很大时)


感谢是前进。

数组列表上迭代,检查每个元素是否以
jon
开头。时间复杂度为O(n)。

您需要迭代每个名称并在其中找到名称

String name = "jon";
int count=0;
for(String n:nameslist){
    if(n.contains(name){
        count++;
    }   
}
“非常慢”到底是什么意思

真正做到这一点的唯一方法是在列表中循环并检查每个元素:

int count = 0;
for (String name : nameslist) {
    if (name.startsWith("jon")) {
        count++;
    }
}

System.out.println("Found: " + count);

ArrayList
(或线性数组)中搜索的复杂性为
O(n)
,其中
n
是数组中的元素数

要获得最佳性能,请查看。它是一种数据结构,旨在根据单词前缀执行快速搜索。为了获得子树中的叶数,您可能需要对其进行一些操作,但无论如何,您都不会遍历整个列表


如果列表中的字符串不太长,您可以使用此技巧:将所有前缀存储在HashSet中,您的复杂性将为~O(1):

//预处理
List List=Arrays.asList(“你好”,“世界”);//你的名单
Set=newhashset()
用于(字符串s:列表){

对于(inti=1;i我建议您创建一个可运行的来处理列表元素。然后您创建一个具有固定池大小的ExecutorService,它同时处理这些元素

粗略的例子:

ExecutorService executor = Executors.newFixedThreadPool(5);
for (String str : coll){
    Runnable r = new StringProcessor(str);
    executor.execute(r);
}
我建议用树丛

类似的方法访问每个元素和增量计数。从算法上讲,您可以提高性能

   int count = 0;
   iter = list.iterator(); 
   String name;
   while(iter.hasNext()) {
        name = iter.next();
        if (name.startsWith("jon")) {
            count++;
        }
        if(name.startsWith("k")) break;
    }

此中断消除了对其余字符串比较的检查。

您可以使用树集进行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);
TreeSet set=newtreeset();
集合。添加(“jon”);
集合。添加(“大卫”);
集合。添加(“戴维斯”);
集合。添加(“jonson”);
集合。添加(“亨利”);
Set子集=Set.tailSet(“jon”);
整数计数=0;
for(字符串s:子集){
如果(s.startsWith(“jon”))计数++;
否则就断了;
}
System.out.println(“count=“+count”);
按你的预期打印2张

可选地,您可以使用<代码> SET子集=SET子集(“乔恩”,“Jo”);< /COD>返回从“代码>乔恩”/CODE >开始的AL名称的完整列表,但是您需要给出遵循JONS的第一个无效条目(在本例中是“Joo”)。


复杂度O(n+m)最坏情况。

您需要指定搜索列表的频率与更改列表的频率。使用树集是一个好主意,但您应该使用它提供的方法来避免循环。目前,您的算法仍然是O(n),与排序的ArrayList相比,不会带来太多收益。
   int count = 0;
   iter = list.iterator(); 
   String name;
   while(iter.hasNext()) {
        name = iter.next();
        if (name.startsWith("jon")) {
            count++;
        }
        if(name.startsWith("k")) break;
    }
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);