2014-11-24 52 views
4

我正在尋找最佳方法來檢查一個字符串是否包含關鍵字列表中的子字符串。如何檢查一個字符串是否有一個來自列表的子字符串?

例如,我創建了一個列表如下:

List<String> keywords = new ArrayList<>(); 
keywords.add("mary"); 
keywords.add("lamb"); 

String s1 = "mary is a good girl"; 
String s2 = "she likes travelling"; 

字符串s1爲從關鍵字「瑪麗」,但字符串s2沒有它。所以,我想定義一個方法:

boolean containsAKeyword(String str, List<String> keywords) 

containsAKeyword(s1, keywords)將返回true,但containsAKeyword(s2, keywords)將返回false。即使只有一個子字符串匹配,我也可以返回true。我知道我可以迭代關鍵字列表並在列表中的每個項目上調用str.contains(),但我想知道是否有更好的方法來遍歷整個列表(避免O(n)複雜性),還是Java爲此提供了任何內置方法。

+0

你可以找到你可以在這裏字符串調用方法:https://docs.oracle.com/javase/7/docs/api/java/lang/String.html我發現它非常有幫助的,通過看所有由String類中的方法定義的標準功能。 – Joop 2014-11-24 17:36:55

回答

6

我會推薦迭代整個列表。值得慶幸的是,你可以使用增強的for循環:

for(String listItem : myArrayList){ 
    if(myString.contains(listItem)){ 
     // do something. 
    } 
} 

編輯知識,你必須以某種迭代列表。想一想,你怎麼知道列表中包含哪些元素而不經過它?

EDIT 2

我可以看到快速運行的迭代的唯一方法就是做以上。按照設計的方式,一旦找到匹配項,它就會提前中斷,而不會進一步搜索。您可以在循環結束時將您的返回false語句放入,因爲如果您檢查完整個列表而沒有找到匹配項,則顯然沒有任何匹配項。下面是一些更詳細代碼:

public boolean containsAKeyword(String myString, List<String> keywords){ 
    for(String keyword : keywords){ 
     if(myString.contains(keyword)){ 
     return true; 
     } 
    } 
    return false; // Never found match. 
} 
+0

只是出於好奇,爲什麼你添加編輯您的文章?我的意思是,如果將其與本文的未來相比較,最後10分鐘只是一小段時間。未來,人們可能會發現編輯的額外好處非常小。就是想。 – Joop 2014-11-24 17:40:35

+1

你是對的,有時我也懷疑自己。但是,我添加(我相信)是有用的,並且相關信息比最初有用的信息更有幫助。把大膽的**編輯**塊可能只是出於習慣。我的意思是,我*正在編輯,對吧? – AdamMc331 2014-11-24 17:43:34

+1

@Joop不是你問這部分,但我覺得編輯2很重要,因爲它解決了更多OP關於解決方案複雜性的問題。雖然這仍然是O(n),但我想要解決可能會縮短迭代的方式。 – AdamMc331 2014-11-24 17:44:51

0

我想你應該檢查存在的方法在String類:

String s1 = "mary is a good girl"; 
if(s1.contains("mary") 
{ 
    //Success 
} 

如果你想提高性能,也許你可以先拆分句子,然後計算所有字符的總和[ASCII值]每個單詞[我們稱之爲散列值]併爲它們中的每一個維護一個單獨的存儲桶(可能是數組),現在當您獲取關鍵字值時,首先找到它的散列值並訪問該數組,然後使其更加高效,他們的長度,然後匹配字符串。

希望有幫助!

+0

您需要檢查'關鍵字'列表中所有單詞的字符串,而不僅僅是一個。 – csmckelvey 2014-11-24 17:29:22

+0

是的。這是我的想法。我想知道在時間複雜性方面我能做得比這更好。 – 2014-11-24 17:30:03

+0

然後,你將不得不通過關鍵字列表循環我猜:) – 2014-11-24 17:30:10

0

您可以在散列圖中的關鍵字中添加所有單詞。然後你可以使用str.contains作爲字符串1和字符串2來檢查關鍵字是否可用。

2

遍歷關鍵字列表,並返回true如果字符串包含關鍵字。否則返回false

public boolean containsAKeyword(String str, List<String> keywords){ 
    for(String k : keywords){ 
     if(str.contains(k)) 
      return true; 
    } 

    return false; 
} 
+0

我不知道爲什麼我對這個問題有一個低估? – 2014-11-24 17:39:16

+0

這不是我,他們逆轉了它,但可能是因爲你之前有一個邏輯錯誤。但是,看起來你找到了它。 – AdamMc331 2014-11-24 17:48:32

1

下面是解

List<String> keywords = new ArrayList<>(); 
keywords.add("mary"); 
keywords.add("lamb"); 

String s1 = "mary is a good girl"; 
String s2 = "she likes travelling"; 
// The function 
boolean check(String str, List<String> keywords) 
    Iterator<String> it = keywords.iterator(); 
    while(it.hasNext()){ 
    if(str.contains(it.next())) 
     return true; 
    } 
    return false; 
} 
2

在JDK8可以做到這一點,如:

public static boolean hasKey(String key) { 
    return keywords.stream().filter(k -> key.contains(k)).collect(Collectors.toList()).size() > 0; 
} 

hasKey(s1); // prints TRUE 
hasKey(s2); // prints FALSE 
0

根據列表的大小,我會建議使用火柴()方法的字符串。 String.matches需要一個正則表達式的說法是,較小的列表,你可以sinply建立一個正則表達式和評價它:

String Str = new String("This is a test string"); 
System.out.println(Str.matches("(.*)test(.*)")); 

這應該打印出「真」。

或者你可以使用java.util.regex.Pattern

相關問題