話說經過了一個晚上的奮戰,我終於搞定了Java該怎麼處理XML(其實應該很簡單),因為這是物件導向程式設計的加分題是要做到中文筆畫排序(英文排序把String Array就丟到Arrays.sort英文排序就搞定了,原因是String有實作Comparable這個Interface),不過中文排序不是不能做,看起來Unicode排列的順序似乎是依照部首(從Word裡看是這樣,不過我沒確定),因此比較Unicode碼是可行的,但是常見的排序應該是注音(漢語拼音?)或者筆畫,所以筆畫排序最重要的就是那張筆畫排序的對照表,
因此,排序表就出現了XD
我相信會來這裡的人都只是要那個XML(結構就像上圖那樣,很單純的),所以,請到下面下載XD(Java實作完成的程式碼和程式也放在一起)
順帶一提,這個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之後自帶會比較好
請按讚:
喜歡 正在載入...
相關