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(); }