簡體   English   中英

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

[英]Fastest way to find substring in JAVA

讓我說我有名單。

ArrayList<String> nameslist = new ArrayList<String>();
nameslist.add("jon");
nameslist.add("david");
nameslist.add("davis");
nameslist.add("jonson");

此列表中包含數千個名單。 知道此列表包含以給定名稱開頭的名稱的方法是什么。

String name = "jon"

結果應該是2。

我已經嘗試將列表的每個元素與子串函數進行比較(它可以工作但是)當列表很大時它非常慢。

謝謝你的提前。

您可以使用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"開頭的al名稱的完整列表,但是你需要給出jons之后的第一個無效條目(在這種情況下:“joo”)。

看看特里 它是一種旨在根據字前綴執行快速搜索的數據結構。 您可能需要稍微操作它以獲取子樹中的葉子數,但無論如何您不會遍歷整個列表。

示例樹

ArrayList (或線性數組)中搜索的復雜性是O(n) ,其中n是數組中元素的數量。

為了獲得最佳性能,您可以看到Trie

迭代ArrayList ,為每個元素檢查它是否以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);

如果列表中的字符串不是太長,你可以使用這個作弊:在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

我建議你創建一個Runnable來處理列表元素。 然后創建一個具有固定池大小的ExecutorService,它同時處理元素。

粗略的例子:

ExecutorService executor = Executors.newFixedThreadPool(5);
for (String str : coll){
    Runnable r = new StringProcessor(str);
    executor.execute(r);
}

我建議TreeSet。

類似的方式訪問每個元素和增量計數。 alogorithm明智的你可以提高性能。

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

這個中斷消除了對其余字符串比較的檢查。

你可以考慮Boyer-Moore字符串搜索算法 復雜度O(n + m)最壞的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM