Giả sử một từ ghép gồm tối đa 4 từ đơn
Đầu vào: Văn bản sText dạng chuẩn (chƣa tách từ) Đầu ra: Văn bản sOutText (đã tách thành các từ ghép)
Ý tƣởng: Xét từng tổ hợp từ từ 4 đến 2 từ, so sánh các tổ hợp này với các từ ghép trong từ điển CompoundDict. Nếu nó xuất hiện trong từ điển thì nó là từ ghép, ngƣợc lại, nó không là từ ghép.
Cách làm nhƣ sau:
Thêm một dấu cách vào cuối văn bản sText để xét trƣờng hợp cuối đoạn có dấu chấm câu. Khi đó ngắt câu sẽ dùng chung qui luật với các đoạn khác.
sText += " ";
Ngắt văn bản sText ra thành các đoạn căn cứ vào các dấu chấm câu: Thay dấu "? " bằng dấu " ?\n "
sText = sText.replace("? ", " ?\n "); Thay dấu ": " bằng dấu " :\n "
sText = sText.replace(": ", " :\n "); Thay dấu "! " bằng dấu " !\n "
sText = sText.replace("! ", " !\n "); Thay dấu ", " bằng dấu " , "
sText = sText.replace(", ", " , "); Thay dấu "; " bằng dấu " ; "
sText = sText.replace("; ", " ; "); Xóa bỏ dấu "\""
Xóa bỏ dấu "' "
sText = sText.replace("' ", ""); Thay hai dấu cách bằng một dấu cách:
sText = sText.replace(" ", " "); Tiến hành ngắt đoạn
Tiếp theo, xét từng đoạn văn một:
Tách đoạn văn thành mảng các từ phân cách nhau bởi dấu cách. - Xét từ đầu tiên của đoạn:
+ Trƣờng hợp 1: Nếu kí tự đầu tiên của từ là kí tự đặc biệt (vd dấu câu nhƣ '?', ':',...) hoặc nó không phải là chữ cái thì bỏ qua. Ở đây các trƣờng hợp sau không đƣợc xem là từ hợp lệ: “?Anh”, “123Em”, “$Usd”,...
+ Trƣờng hợp 2: Từ đầu tiên là một từ hợp lệ (ví dụ từ “xã”), lần lƣợt lấy các từ tiếp theo để xét các tổ hợp từ 4 đến 2 từ:
Ví dụ: Xét tổ hợp từ “xã_hội_chủ_nghĩa”:
Nếu là từ ghép (tức nằm trong từ điển CompoundDict) thì thêm nó vào danh sách văn bản đầu ra sOutText và thêm dấu cách.
Nếu không là từ ghép thì xét tiếp đến tổ hợp “xã_hội_chủ”, nếu vẫn không là từ ghép thì xét tổ hợp cuối cùng là “xã_hội”.
- Tiếp theo ta nhảy đến xét từ ở vị trí kế tiếp, cứ tiếp tục làm nhƣ trên cho tới cuối đoạn văn.
- Nếu vẫn còn từ chƣa thêm vào biến sOutText (trƣờng hợp còn từ cuối cùng) thì ta cứ thế thêm vào.
Mã nguồn của module này nhƣ sau:
private static String splitKeywords(String sText) { StringBuffer sOutText = new StringBuffer(); sText += " "; sText = sText.replace(". ", " .\n "); sText = sText.replace("? ", " ?\n "); sText = sText.replace(": ", " :\n "); sText = sText.replace("! ", " !\n "); sText = sText.replace(", ", " , "); sText = sText.replace("; ", " ; "); sText = sText.replace("\"", ""); sText = sText.replace("' ", ""); sText = sText.replace(" ", " ");
String[] sParagraphArr = sText.split("\n"); for(String sParaItem: sParagraphArr) { String currWord[] = sParaItem.split(" "); int i = 0; while (i < currWord.length - 1) { if (currWord[i].length() <= 0) { i++; continue; }
boolean isAppened = false;
int t = MAX_TOTAL_WORDS_IN_A_COMPOUNDWORD - 1; char ch = currWord[i].charAt(0); //Ký tự đầu của word
if (".,;?:!".indexOf(ch)>= 0 || !Character.isLetter(ch)) { t = 0;
} else {
while (t > 0) {
StringBuffer strTemp = new StringBuffer(); strTemp.append(currWord[i]);
for (int j = i + 1; j < i + 1 + t && j < currWord.length; j++) { strTemp.append("_" + currWord[j]);
}
String tmpWord = strTemp.toString().toLowerCase().trim(); if (WordDict.CompoundDict.containsKey(tmpWord)) { sOutText.append(strTemp + " ");
isAppened = true; //đánh dấu là đã thêm vào chuỗi output break;
} else {
//Nếu ko phải là 1 từ ghép -> xét đến tổ hợp ngắn //hơn bằng cách giảm biến đếm đi 1.
t--; } } } if (t == 0) { if (!isAppened) { sOutText.append(currWord[i] + " "); } } i += t + 1; } if (i < currWord.length) { sOutText.append(currWord[i] + " "); } sOutText.append("\n"); } return sOutText.toString(); }