Đầu vào: văn bản sText là văn bản đã tách từ ghép.
Đầu ra: văn bản sOutText tách thành văn bản đã đoán nhận các danh từ riêng. - Danh từ riêng: là các từ không đứng ở đầu câu gồm ít nhất 2 từ mà chữ cái đầu viết hoa.
- Dùng một vector để lưu danh sách các danh từ riêng (tên riêng) đã tìm được.
- Hàm (phương thức) IsName để kiểm tra xem một từ có phải là danh từ riêng (tên riêng) hay không (tức kiểm tra xem chữ cái đầu của từ đó có viết hoa không, đồng thời nó không phải là từ ghép đã đoán nhận).
Cách tách như sau:
Bước 1: Ngắt văn bản thành các câu phân cách nhau bởi dấu xuống dòng hoặc dấu chấm câu.
Bước 2: Ngắt mỗi câu thành mảng các từ đơn.
Bước 3: Với mỗi câu văn bản:
Bỏ qua các từ viết hoa liền nhau ở đầu câu.
Xét từng từ một, nếu thấy từ dạng tên riêng mà không đứng ở đầu câu thì lưu lại vào biến tạm aName. Khi có 2 từ liền nhau trở lên được lưu vào biến tạm, đồng thời từ tiếp theo không phải là dạng tên riêng, thì ta thêm aName vào danh sách danh từ riêng (lưu vào vector).
Mỗi lần lưu một danh từ riêng vào vector xong, ta xóa rỗng biến tạm để chuẩn bị xét đến từ tiếp theo.
Cứ tiếp tục làm như vậy cho đến khi hết câu văn.
Bước 4: Xét ngược lại các trường hợp danh từ đứng ở đầu câu. Nếu một danh từ riêng đã được xác định ở chỗ khác trong câu thì khi đó, nếu nó xuất hiện ở đầu câu (trường hợp đã bỏ qua khi xét ở trên) thì nó cũng là danh từ riêng.
Với mỗi từ trong danh sách tên riêng, ta thay dấu cách phân cách từ bằng dấu gạch dưới và lưu vào biến realName.
Với mỗi câu văn bản, ta thay tất cả những tên riêng aName bằng tên riêng realName (ví dụ thay hết các từ dạng “Nguyễn Văn A” thành dạng “Nguyễn_Văn_A”).
Tiếp tục như trên cho tới khi hết thay thế hết tất cả các từ trong tất cả các câu văn.
Hạn chế: Đối với các tên riêng chỉ xuất hiện ở đầu câu mà không xuất hiện ở những vị trí khác thì chương trình chưa phát hiện ra. Ví dụ:
Văn bản 1: Chủ tịch Hồ Chí Minh vĩ đại sống mãi trong sự nghiệp của chúng ta. Văn bản 2: Hồ Chí Minh muôn năm. Hồ Chí Minh là một danh nhân văn hóa
thế giới.
Khi tính độ tương tự, hai văn bản trên được tách từ như sau:
Văn bản 1: Chủ_tịch Hồ_Chí_Minh vĩ_đại sống mãi trong sự_nghiệp của chúng_ta.
Văn bản 2: Hồ Chí Minh muôn năm. Hồ Chí Minh là một danh_nhân văn_hóa thế_giới.
Ở ví dụ trên, mặc dù từ Hồ Chí Minh xuất hiện 2 lần trong văn bản 2 nhưng vì đứng ở đầu câu nên nó vẫn không được nhận biết là tên riêng.
Mã nguồn của module này như sau:
private static String splitNameWords(String sText) { StringBuffer sOutText = new StringBuffer();
Vector<String> vNameList = new Vector<String>(); String[] sParagraphArr = sText.split("\n");
for(String sParaItem: sParagraphArr) { String strWordArr[] = sParaItem.split(" "); boolean isFirstPositionOfParagraph = true; StringBuffer aName = new StringBuffer(); for (int i = 0; i < strWordArr.length; i++) { String currWord = strWordArr[i];
if (isFirstPositionOfParagraph) { if (!isName(currWord)) {
isFirstPositionOfParagraph = false; }
} else {
boolean hasName = false; if (isName(currWord)) { aName.append(currWord + " "); hasName = true; } if (!hasName || i == strWordArr.length - 1) { if (aName.length() > 0) { if (aName.toString().trim().indexOf(' ') > 0) { vNameList.addElement(aName.toString().trim()); }
aName.delete(0, aName.length()); } } } } }
//Xét ngược lại các trường hợp danh từ đứng ở đầu câu. for(String sParaItem: sParagraphArr) {
sParaItem = " " + sParaItem + " "; for (String aName: vNameList) {
String realName = aName.replace(' ', '_');
sParaItem = sParaItem.replace(" " + aName + " ", " " + realName + " "); }
sOutText.append(sParaItem.trim() + "\n"); }
return sOutText.toString(); }