中文筆畫排序表XML(含Java實作程式碼XD)~

話說經過了一個晚上的奮戰,我終於搞定了Java該怎麼處理XML(其實應該很簡單),因為這是物件導向程式設計的加分題是要做到中文筆畫排序(英文排序把String Array就丟到Arrays.sort英文排序就搞定了,原因是String有實作Comparable這個Interface),不過中文排序不是不能做,看起來Unicode排列的順序似乎是依照部首(從Word裡看是這樣,不過我沒確定),因此比較Unicode碼是可行的,但是常見的排序應該是注音(漢語拼音?)或者筆畫,所以筆畫排序最重要的就是那張筆畫排序的對照表,

因此,排序表就出現了XD

image

我相信會來這裡的人都只是要那個XML(結構就像上圖那樣,很單純的),所以,請到下面下載XD(Java實作完成的程式碼和程式也放在一起)

image

順帶一提,這個XML我已經處理過了,所以如果要用JavaScript在Firefox裡做分析的話是不會出現\n被當成一個Textnode的情形的,然後也歡迎擴充XD(如果有擴充的話也歡迎來交流一下XD)

一開始在做作業的時候因為找不到中文筆畫排序該怎麼實作(我第一個想到就是丟到MySQL裡),所以找到了這位大陸高手的部落格(http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html),但是看到文章中段的「人工校正」我想到就累,於是又在網路上搜尋了一下,又找到了一篇號稱「國家語發委」(有這衙門嗎?)作的繁體簡體字筆劃(筆順?)對照表(http://www.iphone.org.hk/cgi-bin/ch/threaded_show.cgi?tid=932&pid=4968&age=0&bpg=6),大致上看了一下應該是沒有什麼錯誤的,唯一的缺點應該就是他是一個Excel檔案,我知道C#要開Java可以透過呼叫COM+,但是Java就真的不知道了(應該也有API吧),再者說萬一助教電腦上沒有Excel,不就囧了嗎XD

所以我就把Excel檔案存成XML之後再用C#寫之程式把結構改成比較好讀的,在手動補上一個DTD就成為了現在這份中文筆畫排序表,要使用的方法應該很簡單,就用JDK裡帶的org.w3c.dom.*裡的Document這個Class把XML給分析好,然後就用一般操作XML的方式去getElementById(‘中文字’)就可以了,因為Java的char是8-bit的,所以對UTF-8支援沒有問題,所以用中文當作id當然更沒有問題,唯一的問題就是得注意要是你的文字檔案讀入時沒有指定UTF-8編碼,就科科了

那反正取得到那個node裡的FirstChild().getTextContent()就是筆畫了(為什麼要用getTextContent?因為我記得Element的nodevalue是null(https://developer.mozilla.org/En/DOM/Node.nodeValue),不過我不知道Java是不是,只是習慣而已),其他兩個UFT-8和GBK編碼值就當聊備一格吧~

然後不得不說Java真是很繁瑣,這種事情用C#可以很清楚的寫出來,至少不會StreamReader還要我指定UTF-8編碼,using System.Xml也比Java掛來掛去輕鬆愉快,真是囧

於是該怎麼用Java、C#實作IComparator、IComparable,我這邊只能提供一個寫得或許不是很好的版本,反正可以讓我帶進去Arrays.sort,然後把筆畫越少的擺越前面就對了

另外,謝謝billmeteor,讓我找到原本算法的錯誤XD

//中文排序

public int compare(String a, String b) {

  char[] obja = a.toCharArray();

  char[] objb = b.toCharArray();

  for (int k = 0; k < obja.length; k++) {

    String str1, str2;

    boolean aisenglish, bisenglish;

    boolean bshort = false;

    //檢查是不是英文

    aisenglish = obja[k] + 0 >= 32 && obja[k] + 0 <= 126 ? true : false;

    str1 = String.valueOf(obja[k]);

    try {  //如果發生字串2比字串1短的時候的處理方法

      bisenglish = objb[k] + 0 >= 32 && objb[k] + 0 <= 126 ? true : false;

      str2 = String.valueOf(objb[k]);

    } catch (Exception e) {

      str2 = “";

      bisenglish = aisenglish;  //如果是第一個字串是英文,就丟給String自己的comparable處裡

      bshort = true;

    }

    if (!aisenglish && !bisenglish) {

      int comval = 0;

      int str1val, str2val;

      try {

        str1val = Integer.parseInt(CHStoke.getElementById(str1).getFirstChild().getTextContent());

      } catch (Exception e) {

        str1val = 0;

      }

      try {  //如果不在這張表裡面的處理方法

        if(!bshort) {

          str2val = Integer.parseInt(CHStoke.getElementById(str2).getFirstChild().getTextContent());

        } else {

          str2val = 0;

        }

      } catch (Exception e) {

        str2val = str1val;

        str1val = 0;

      }

      comval = str1val – str2val;  //比較的原則就是回傳值越大的,排在越後面

      if (comval == 0) {

        continue;

      } else {

        return comval;

      }

    } else {

      int comval = str1.compareTo(str2);

      if (comval == 0) {

        continue;

      }

      return comval;

    }

  }

  return obja.hashCode() – objb.hashCode();  //都沒辦法的時候只能交給Hashcode比較了

}

我沒有提供完整的程式碼,這個函式是可以運作的,但是不能直接給Array.sort用,還得實做一個東西才行喔XD(我應該沒有公布答案吧@@")

喔對如果是跟我遇到一樣問題的同學或學弟妹,就不需要感謝我了,反正我也不是資訊系的XD

P.S.

順帶一提,教育部其實有提供異體字字典(http://dict.variants.moe.edu.tw/yitia/fra/fra02552.htm),裡面有中文筆畫資訊(不得不說非常詳細,包括扣掉部首之後的筆畫和全部筆畫,還有有些字我怎麼寫都寫不到這麼多筆畫的筆畫XD),如果可以連上網的話當然也可以透過分析DOM、REGXP等方式分析,只是它非常不好查詢(得經過教育部另外一套系統來查會比較好查:http://www.nlcsearch.moe.gov.tw/EDMS/admin/dict3/),但是很明顯的不好用,然後萬一助教故意把網路關掉也很囧,乾脆就別用了,還是XML在JDK 1,4還是1,5之後自帶會比較好

在〈中文筆畫排序表XML(含Java實作程式碼XD)~〉中有 11 則留言

  1. 雖然知道是用什麼做的

    但我對java還不是很厲害

    請問有寫好的完整程式碼可以借我看嗎?

  2. 嗯好,我已經把測試程式放在和筆畫表一樣的地方,另外也寄到您信箱囉
    其實我也才學一學期而已,寫的不好請多多指教@@"

  3. 先謝謝你給我範例的檔案︿︿

    可是我執行了以後發現有一些亂碼

    排序的結果除了英文以外其他好像是亂碼

    請問有辦法解決嗎?

  4. 你是執行範例程式碼發生錯誤嗎?
    我等下把我的執行畫面記給你看
    如果你是要讀入某一個文字檔案的話,請用下面的語法(強制使用UTF-8讀入),因為Document Class是用UTF-8的,一般的BufferedReader不一定用UTF-8
    new BufferedReader(new InputStreamReader(new FileInputStream(“檔案名稱"),"UTF-8″));

  5. 其實我也不太清楚@@"

    應該是範例裡的程式碼編碼不同的問題

    因為我沒有用到上面那個語法

  6. 沒有阿

    我用的還是你的演算法

    我說沒用到的語法是new BufferedReader(new InputStreamReader(new FileInputStream(”檔案名稱”),”UTF-8″));

  7. 看到此java的中文筆畫排序表Xml…非常羨幕,不過我想問站長,有PHP + Mysql 的中文筆畫順序嗎?? @@

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料