伊莉討論區

標題: 請問如何把讀到的文檔用空白鍵分割英文字串? [打印本頁]

作者: ray215018    時間: 2012-6-13 03:53 AM     標題: 請問如何把讀到的文檔用空白鍵分割英文字串?

我主要是 讀txt檔 把裡面的英文分開計算出現次數 再轉出一個txt檔
例如:I is apple
I  1
is  1
apple 1
讀取跟輸出txt檔都ok
就是在把文章分割字串有錯誤
本來想要判斷空白鍵做分割但是都沒成功
希望可以用成空白或是特殊符號都可以分割
請教各位大大我的程式是不是那裡有錯誤?

import java.io.*;
import java.util.*;
public class java2
{
  public static void main (String[] args) throws IOException
  {
    String               fileName   = "test1.txt";
    BufferedReader       bufReader  = new BufferedReader (new FileReader (fileName));   
    StreamTokenizer      stToken    = new StreamTokenizer (bufReader);
    Map<String, Integer> mapWords   = new HashMap<String, Integer> ();
    Set                  mapSet     = null;
    Map.Entry[]          mapEntries = null;   
    Integer              numWords   = null;
    int                  tokenType  = 0;
    int                  i;
    // 小寫(lower case)模式
    stToken.lowerCaseMode (true);
   
    // 除了a - z 及 A - Z, 其餘皆設為ordinary chars
    stToken.ordinaryChars (0, 'A' - 1);        
    stToken.ordinaryChars ('Z' + 1, 'a' - 1);        
    stToken.ordinaryChars ('z' + 1, 255);   
    // 處理end of line
    stToken.eolIsSignificant (true);
for(i=0;bufReader.ready ();i++){
String temp=stToken.nextToken().toString();
String wordtemp[]=temp.split("\\s+");
}

   
// 把所有單字及累計的字數存入HashMap裡
    while (bufReader.ready ())
    {
       tokenType = stToken.nextToken ();
      
      switch (tokenType)
      {
      case StreamTokenizer.TT_WORD:
        {
          // 取得Hashtable內累計的次數
          numWords = mapWords.get (stToken.sval);
         
          if (numWords == null)
          {
            // 若不存在,設定為第一次
            numWords = new Integer (1);
          }
          else
          {
            // 累加字數
            numWords++;
          }
         
          // 存回Hashtable
          mapWords.put (stToken.sval, numWords);
        }
        break;
        
      default:
        break;
      }
    }   
   
    // 把HashMap依值排序
    mapSet     = mapWords.entrySet ();
    // 轉成陣列後排序
    mapEntries = (Map.Entry[]) mapSet.toArray (new Map.Entry[mapSet.size ()]);
    // 排序
    Arrays.sort (mapEntries, new Comparator ()
                              {
                                public int compare (Object o1, Object o2)
                                {
                                 Object v1 = ((Map.Entry)o1).getValue ();
                                 Object v2 = ((Map.Entry)o2).getValue ();
                                 return ((Comparable)v2).compareTo (v1);
                                }
                              }
                );
               
    // 輸出test.txt     
   BufferedWriter bw = new BufferedWriter
        (new FileWriter("test.txt"));
           
    for (i = 0; i < mapEntries.length; i++)
    {
         bw.write(  mapEntries.getKey () + " " + mapEntries.getValue ()+"\r\n" );
    }               
        bw.close();
  }
}


作者: BlueMarken    時間: 2012-6-13 09:11 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: BlueMarken    時間: 2012-6-13 11:27 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-13 03:39 PM

BlueMarken 發表於 2012-6-13 11:27 AM
花了一點時間學習 StreamTokener,順便Debug一下程式,我的範例如下,不知道是否符合你的需求: ...

謝謝大大 的確很符合 只是還有 讀取txt檔
我是想把大大教的
String svalue = "There are two apples, three oranges\n\r and four tomatos.\n"

        + "The promble is '-' whether it is a token or not.";

    StreamTokenizer st = new StreamTokenizer(new StringReader(svalue));

更改成
String               fileName   = "test1.txt";
    BufferedReader       bufReader  = new BufferedReader (new FileReader (fileName));
    StreamTokenizer st = new StreamTokenizer(new StringReader(bufReader));
不過會有錯誤在最後一個
作者: BlueMarken    時間: 2012-6-13 08:11 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: BlueMarken    時間: 2012-6-13 08:11 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-13 08:41 PM

BlueMarken 發表於 2012-6-13 08:11 PM
StreamTokenizer()建構時,直接丟bufReder就可以了。
參考:

大大 我剛剛改完之後 執行出來的結果又變成了 純單字而已
原本的執行 是  有分解英文字詞
然後改取txt檔之後 又變成 只分解了a  b  c 之類的單字
我的test1.txt要讀的檔的內容如下
<papers>        
        <paper>
                <title>A corporatecreditratingmodelusingmulti-classsupportvectormachines
with anordinalpairwisepartitioningapproach</title>
                <authors>Kyoung-jae Kim a,HyunchulAhn</authors>
                    <journal>Computers & OperationsResearch</journal>
                <year>2012</year>
                <vol>39</vol>
                <pages>1800-1811</pages>
                <abstract>
Predicting corporate credit-rating using statistical and artificial intelligence (AI) techniques has received considerable research attention in the literature. In recent years, multi-class support vector machines (MSVMs) have become a very appealing machine-learning approach due to their good performance. Until now, researchers have proposed a variety of techniques for adapting support vector machines (SVMs) to multi-class classification, since SVMs were originally devised for binary classifica- tion. However, most of them have only focused on classifying samples into nominal categories; thus, the unique characteristic of credit-rating – ordinality – seldom has been considered in the proposed approaches. This study proposes a new type of MSVM classifier (named OMSVM) that is designed to extend the binary SVMs by applying an ordinal pairwise partitioning (OPP) strategy. Our model can efficiently and effectively handle multiple ordinal classes. To validate OMSVM, we applied it to a real-world case of bond rating. We compared the results of our model with those of conventional MSVM approaches and other AI techniques including MDA, MLOGIT, CBR, and ANNs. The results showed that our proposed model improves the performance of classification in comparison to other typical multi-class classification techniques and uses fewer computational resources.
                </abstract>
                <keywords>
Corporate credit rating Support vector machines Multi-class classification Ordinal pairwise partitioning
                </keywords>
                <content>
作者: BlueMarken    時間: 2012-6-13 10:44 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-13 10:57 PM

BlueMarken 發表於 2012-6-13 10:44 PM
你要Parser的檔案,看來像 XML 檔案,你必須仔細的想想你的需求是什麼。
處理 xml 檔是另外一回事。
...

嗯 我還是讀txt檔 只是裡面可能會有似類xml格式
所以我在想是不是還要再判斷 空白鍵 <  >  \之類的
st.ordinaryChar(' ');
st.ordinaryChar('<');
st.ordinaryChar('>');
不過不能執行
作者: BlueMarken    時間: 2012-6-14 10:34 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-14 08:25 PM

BlueMarken 發表於 2012-6-14 10:34 AM
我測試過你貼上來的文字檔,可以執行喔,你要不要貼上你的錯誤訊息。
另外,我是用 JDK 7 去執行的(有用到 ...

只是我用執行完變成這樣
可以執行 是有寫2行錯誤
Note: java2.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

e 151
a 134
i 128
t 118
s 114
o 113
r 108
n 97
c 79
l 66
p 61
d 49
h 48
m 45
u 41
g 27
f 26
v 26
y 23
w 16
b 10
q 5
k 4
j 3
? 1
x 1

作者: ray215018    時間: 2012-6-14 10:53 PM

我就是把txt讀取 跟輸出的地方改過
但是跑出來的結果跟大大的不一樣
  1. //package sliptstring;
  2. import java.io.*;
  3. import java.util.*;
  4. import java.io.IOException;
  5. import java.io.StreamTokenizer;
  6. import java.io.StringReader;
  7. import java.util.ArrayList;
  8. import java.util.Collections;
  9. import java.util.Comparator;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.Map.Entry;

  14. /**
  15. *
  16. * @author marken
  17. */
  18. public class SliptString {

  19.   /**
  20.    * @param args the command line arguments
  21.    */
  22.   public static void main(String[] args) throws IOException {
  23.    
  24.    
  25.     String               fileName   = "test2.txt";
  26.     BufferedReader       svalue  = new BufferedReader (new FileReader (fileName));   
  27.     StreamTokenizer      st    = new StreamTokenizer (svalue);

  28.     st.lowerCaseMode(true);
  29.     //st.eolIsSignificant (true);
  30.     st.ordinaryChar('.');

  31.     Map<String, Integer> mapWords = new HashMap<>();
  32.     out:
  33.     while (true) {
  34.       int ttype = st.nextToken();
  35.       switch (ttype) {
  36.         case StreamTokenizer.TT_EOF:
  37.           break out; // 這一行才能正確的跳出 while 迴圈
  38.         case StreamTokenizer.TT_WORD:
  39.           // 取得Hashmap內累計的次數
  40.           Integer numWords = mapWords.get(st.sval);
  41.           numWords = (numWords == null ? 1 : ++numWords);
  42.           // 存回次數
  43.           mapWords.put(st.sval, numWords);
  44.       }
  45.     }
  46.     // 依出現的次數排序, 遞減排序,最多次的最前面
  47.     List<Map.Entry<String, Integer>> mapEntries = new ArrayList<>(mapWords.entrySet());
  48.     Collections.sort(mapEntries,new Comparator<Map.Entry<String, Integer>>(){

  49.       @Override
  50.       public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
  51.         return o2.getValue().compareTo(o1.getValue());
  52.       }
  53.     });
  54.     // 印出結果
  55. BufferedWriter bw = new BufferedWriter
  56.         (new FileWriter("test.txt"));

  57.     for(Map.Entry<String, Integer> entry : mapEntries) {
  58.       bw.write(String.format("%s:%d", entry.getKey(),entry.getValue())+"\r\n");
  59.     }
  60. bw.close();
  61.   }
  62. }
複製代碼

作者: BlueMarken    時間: 2012-6-15 07:50 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-16 07:03 AM

BlueMarken 發表於 2012-6-15 07:50 PM
我照你的程式跑,沒問題。我猜可能是環境的問題。
我是用 jdk 7u5 ,你有檢查過你的環境? 另外,你的文 ...

的確是可以執行成功  感謝你
我原本是用 javac SliptString.java     java SliptString  做執行的動作

只是如果txt裡的檔太大還是會變成我前面貼的那個樣子
因為我讀的txt裡面的資料很多 我只是貼一部份

還有另一個問題 如何去除特殊符號 <>\?.,等?
我執行後輸出到新的txt裡面 a:6 那個英文字詞 跟次數中間的:可以改空白嗎?
bw.write(String.format("%s:%d", entry.getKey(), entry.getValue()) + "\r\n");
是不是改成這樣?
bw.write(String.format(" ", entry.getKey(), entry.getValue()) + "\r\n");



作者: BlueMarken    時間: 2012-6-16 07:57 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ray215018    時間: 2012-6-17 05:43 AM

好的 感謝你
我再研究一下String.format()用法




歡迎光臨 伊莉討論區 (http://www49.eyny.com/) Powered by Discuz!