2017-08-16 99 views
2

一個文本文件,我已經從GitHub的項目,看起來一個文本文件(所有有效的英語單詞集合)這樣words.txt檢查一個字符串包含在單詞中的Java

我的文本文件是下resources我的項目中的文件夾。

我也有從mysql中的表中獲得的行的列表。 我想要做的是檢查每一行中的所有單詞是否都是有效的英文單詞,這就是爲什麼我將每行與包含在我的文件中的單詞進行比較。

這是我試過到目前爲止:

public static void englishCheck(List<String> rows) throws IOException { 
    ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 
    int lenght, occurancy = 0; 
    for (String row : rows){ 

     File file = new File(classLoader.getResource("words.txt").getFile()); 


     lenght = 0; 

     if (!row.isEmpty() ){ 
      System.out.println("the row : "+row); 
      String[] tokens = row.split("\\W+"); 
      lenght = tokens.length; 
      for (String token : tokens) { 

       occurancy = 0; 
       BufferedReader br = new BufferedReader(new FileReader(file)); 

       String line; 
       while ((line = br.readLine()) != null){ 


        if ((line.trim().toLowerCase()).equals(token.trim().toLowerCase())){ 
         occurancy ++ ; 

        } 
        if (occurancy == lenght){ System.out.println(" this is english "+row);break;} 

       } 

      } 





     } 

    } 
} 

這隻有在首先行,在那之後我的方法遍歷行只顯示他們忽略了對比,我想知道這是爲什麼不爲我行集的工作,它的工作原理也是,如果我預先設定我的名單像這樣List<String> raws = Arrays.asList(raw1, raw2, raw3)

+0

超級壞主意:你在這裏創建一個n * m雙循環。你絕對不會**一次又一次地爲你的每一個單詞讀這個文件。 – GhostCat

+0

@DevRj /words.txt中數據的格式是什麼?它是一行一行的在同一行,給一個樣本 –

+0

提示:當你*編輯*你的源代碼...確保正確格式化它。 – GhostCat

回答

1

您可以閱讀words.txt文件,轉換詞成小寫,然後坐言HashSet

使用boolean contains(Object o)boolean containsAll(Collection<?> c);方法來比較每個單詞。 時間爲O(n)

提示:不要在每個循環中讀取文件。讀取文件非常慢。

ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 
InputStream inputStream = classLoader.getResourceAsStream("words.txt"); 
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
List<String> wordList = new LinkedList<String>(); // You do not know word count, LinkedList is a better way. 
String line = null; 
while ((line = reader.readLine()) != null) { 
    String[] words = line.toLowerCase().split("\\W+"); 
    wordList.addAll(Arrays.asList(words)); 
} 
Set<String> wordSet = new HashSet<String>(wordList.size()); 
wordSet.addAll(wordList); 


// then you can use the wordSet to check. 
// You shold convert the tokens to lower case. 
String[] tokens = row.toLowerCase().split("\\W+"); 
wordSet.containsAll(Arrays.asList(tokens)); 
+0

有用的答案就像你可以直接傳遞一些值,而不是'Set wordSet = new HashSet (wordList.size()); (wordList);''你可以簡單地這樣做:'設置 wordSet = new HashSet (wordList);',謝謝 – DevRj

+0

是的。你是對的。謝謝。 – diguage

2

您可以使用該方法List#containsAll(Collection)

如果此列表包含 指定集合的​​所有元素,則返回true。

讓我們假設你有兩個列表flled myListFromRessourcesmyListFromRessources那麼你可以做:

List<String> myListFromRessources = Arrays.asList("A", "B", "C", "D"); 
List<String> myListFromRessources = Arrays.asList("D", "B"); 

boolean myInter = myListFromRessources.containsAll(myListFromSQL); 
System.out.println(myInter); 
myListFromSQL = Arrays.asList("D", "B", "Y"); 
myInter = myListFromRessources.containsAll(myListFromSQL); 
System.out.println(myInter); 
+0

您還想添加一些關於可能立即將該文件讀入內存的信息。 – GhostCat

+0

不是真的,這就是爲什麼我寫道:***「讓我們假設你有兩個列表填充」*** ...我假設OP知道如何做,因爲他沒有在代碼中提及任何問題... –

+0

我的文件是從github項目下載的一組英文單詞,並且我對我的SQL表包含的內容沒有清楚的認識,它可能包含一些無意義的單詞('row =「ghsjgsdh hg.hg」'' )或半英語單詞row =「半英語句子hkdojgsv hdh」)或有效的一行=「有效英語句子」',我似乎無法理解您的建議如何適合我的情況 – DevRj

1

您的代碼不起作用的原因是occurancy不能超過0或1以外的任何其他你可以看到,按照邏輯或通過調試器去。

如果您的words.txt文件不是太大,並且您有足夠的RAM可用,則可以通過在開始時將words.txt文件讀入內存來加速處理。此外,你只需要一次調用toLowerCase(),而不是每次比較。但是,請注意區域設置。只要您沒有任何非英文字符,如德語eszett或希臘語西格瑪,以下代碼應該可以工作。

public static void englishCheck(List<String> rows) throws IOException { 
    final URI wordsUri; 
    try { 
     wordsUri = ClassLoader.getSystemResource("words.txt").toURI(); 
    } catch (URISyntaxException e) { 
     throw new AssertionError(e); // can never happen 
    } 

    final Set<String> words = Files.lines(Paths.get(wordsUri)) 
      .map(String::toLowerCase) 
      .collect(Collectors.toSet()); 

    for (String row: rows) 
     if (!row.isEmpty()) { 
      System.out.println("the row : " + row); 
      String[] tokens = row.toLowerCase().split("\\W+"); 
      if (words.containsAll(Arrays.asList(tokens))) 
       System.out.println(" this is english " + row); 
     } 
} 
相關問題