Thursday, December 28, 2006

เสริม ICU4J

bact' เขียนเรื่อง Using dictionary with ICU4J BreakIterator
เห็น code ที่ bact' ใช้ในการ initialize
String rules = (RuleBasedBreakIterator.getWordInstance(new Locale ("th"))).toString();

ในส่วนของการได้มาซึ่ง rules มันดูแปลกๆ
ก็เลยไปนั่งไล่ code ดูว่ามันมาจากไหนกันแน่

เริ่มแรกสุด method getWordInstance มันเป็น static method
ใน class BreakIterator
ดังนั้นถ้าจะเขียนให้สื่อหน่อย อาจจะเขียนอย่างนี้แทน
String rules = BreakIterator.getWordInstance(new Locale ("th")).toString()


method getWordInstance ไม่ได้สร้าง BreakIterator เอง
แต่ delegate งานไปให้ BreakIteratorFactory เป็นคนทำ
ซึ่ง BreakIteratorFactory จะใช้กลไก ResourceBundle ในการค้นหา
ว่าจะใช้ rule file ตัวไหนดี

จากการ debug, ตัว rule file จะใช้ file
com/ibm/icu/impl/data/icudt36b/brkitr/word.brk
ภายในเป็น binary file ก็เลยไม่รู้ว่ามีเนื้อหาอะไรบ้าง

เมื่อได้ rule มาแล้ว
BreakIteratorFactory มันจะสร้าง BreakIterator ให้เราโดยใช้คำสั่งนี้
//TODO: Hard code this for now! fix it once CompactTrieDictionary is ported
if(locale.equals("th")){
String fileName = "data/th.brk";
InputStream is = ICUData.getStream(fileName);
iter = new DictionaryBasedBreakIterator(ruleStream, is);
}

Note: สังเกตุ comment ใน Todo ด้วย

ดังนั้นตัวอย่างของ bact'
ถ้าเขียนใหม่ให้ชัดเจนไปเลยว่า rule มาจากไหน
อาจจะเขียนดังนี้
InputStream rules = ICUData.getStream("data/icudt36b/brkitr/word.brk");
InputStream dict = new FileInputStream("tdict.dic");

DictionaryBasedBreakIterator iter =
new DictionaryBasedBreakIterator(rules, dict);

Related link from Roti

2 comments:

bact' said...

ขอบคุณมาก ๆ ครับพี่ :D

Anonymous said...

ขอถามหน่อย DictionaryBasedBreakIterator ของ icu4j ใช้อัลกอลิทึม แบบไหนนะ เป็น
Longest matching หรือ
Maximal matching หรืออย่างอื่นนะ
ขอบคุณนะ ได้ความรู้มากเลย