簡體   English   中英

對於具有多個單詞的輸入字符串 - 檢查它們中的任何一個是否以其他字符串開頭的最有效方法是什么?

[英]For input string with multiple words - what is the most efficient way to check if any of them start with some other string?

我需要實現一個 java 方法,該方法獲取字符串集和輸入字符串,並返回字符串的子集,其中包含原始集合中具有以輸入字符串開頭的任何單詞的所有字符串。 例如,如果一個字符串是“Stack Overflow”,而輸入是“Over”,它應該在子集中。 但是如果一個字符串是“Stack Overflow”,而輸入是“flow”,它就不應該在子集中。

public Set<String> findMatches (Set<String> names, String input);

由於集合大小很大(1 億),我需要以最有效的方式進行。 到目前為止,我嘗試過的三種方法都帶來了令人困惑的結果:

  1. 用空格分割每個字符串並獲得字符串數組,然后,在數組中的每個項目上 - 調用 String 的 startsWith 方法。
  2. 對於每個字符串,檢查它是否以輸入開頭,包含“”+輸入(空格后跟輸入)。
  3. 正則表達式。

我測試了這些方法並測量了時間,但令人驚訝的是 - 對於不同的輸入值(字符串集和輸入字符串) - 我得到了不同的結果(選項 1 在大多數情況下獲得了最好的結果,但與其他選項的結果非常接近) .

那么哪一種是最有效的呢? 還有其他我沒有想到的選擇嗎?

您需要的數據結構是try

在這個解釋中,我的意思是t_i是應該作為單詞前綴的小字符串,而s是包含許多用空格分隔的單詞的大字符串。

只需在特里添加所有t_i 然后遍歷s字符:

  • 如果遇到空格,請轉到 trie 的根。

  • 如果您遇到一個字母,請從當前的樹節點轉到與該字母關聯的子節點。 如果沒有路徑,只需跳過所有字母,直到遇到下一個空格。 如果您到達鏈接到t_i之一的節點,請添加該字符串以進行回答。

該算法在O(sum(length(t_i)) + length(s))起作用。 如果需要,我可以編寫一些代碼。

@DudeDoesThings 建議的所有算法和算法都在O(sum(length(t_i)) * length(s)) ,這要慢得多,尤其是在涉及大輸入時。

如果您確實有數百萬個字符串並且需要效率,我建議您不要使用拆分或正則表達式。 也許您想研究 Stream API,尤其是並行流,如果您關心的是計算速度:

public static void main(String[] args) {
    Set<String> s = Arrays.stream(new String[] {
        "Stack Overflow",
        "Flowover Stack",
        "Overflow Stack",
        "Stackover Flow"
    }).collect(Collectors.toSet());
    System.out.println(findMatches(s, "Over"));
}

public static Set<String> findMatches (Set<String> names, String input) {
    int inputLength = input.length();
    return names.stream().parallel().filter(name -> {
        int offset = 0;
        while (offset >= 0 && offset + inputLength < name.length()) {
            if (name.startsWith(input, offset)) {
                return true;
            }
            offset = name.indexOf(" ", offset);
            if (offset != -1) {
                offset++;
            }
        }
        return false;
    }).collect(Collectors.toSet());
}

暫無
暫無

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

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