이 기사에서는 Java가 구현 한 양방향 일치 단어 세분화 알고리즘에 대해 설명합니다. 다음과 같이 참조에 대해 공유하십시오.
몇 가지 인기있는 단어 세분화 알고리즘은 다음과 같습니다. 문자열 매칭을 기반으로하는 단어 세분화 방법, 이해에 기초한 단어 세분화 방법 및 통계에 기반한 단어 세분화 방법. 이 기사는 문자열 일치 방법을 사용합니다.
최대 일치하는 분사 :
이 알고리즘은 문자열의 왼쪽에서 세분화 일치를 수행하는 단어 분사 사전을 기반으로 구현됩니다. 사전이 존재하면 분할 된 단어를 반환하고 이전 문자열에서 단어를 자르고 문자열 크기가 0이 될 때까지 고리를 잘라냅니다.
예를 들어 : STR = "우리는 Northwest A & F University의 School of Information Engineering의 학생들입니다."
1. 분사 길이 len = max라는 단어를 정의하고, 왼쪽 단어에서 Len 문자를 꺼내십시오 = "우리는 모두 북서쪽 농업과 임업입니다."
2. 사전에 그러한 단어가 없으면 마지막 문자를 제거하고 단어에 할당하면 Len 값이 1만큼 줄어 듭니다.
3. 단어가 사전 또는 len = 1에서 발견 될 때까지 2 단계를 반복하고 루프를 종료하십시오.
4. STR에서 분할 된 단어를 잘라 내고 STR이 분해 될 때까지 1, 2 및 3 단계를 반복하십시오.
최대 일치하는 분사를 역전시킵니다 :
전방 단어 세그먼테이션 알고리즘과 마찬가지로 문자열의 길이가 0이 될 때까지 문자열의 오른쪽에서 단순히 시작됩니다. 여기서는 자세히 설명하지 않습니다.
양방향 일치하는 분사 :
이 방법은 전진 분사 및 역 분사를 기반으로 모호성을 분할하기위한 모호성 분사를 만드는 것입니다. "뱀 먹는 알고리즘"의 구현을 제안하십시오. 단어 세분화를 수행하는 문자열은 음식입니다. 2 개의 멍청한 뱀이 있으며, 하나는 왼쪽에서 오른쪽으로 먹습니다. 다른 하나는 오른쪽에서 왼쪽으로 먹습니다. 왼쪽과 오른쪽 분사 결과가 모호한 한 두 뱀이 물게됩니다. 뱀이 먹는 끈은 분사가됩니다. 왼쪽과 오른쪽 분사 사이에 항상 모호함이 있다면 두 뱀은 계속 먹을 것입니다. 두 뱀이 줄 사이의 교차점을 먹으면 분명히 모호성이 없습니다. 이 시점에서 왼쪽의 욕심 많은 뱀 배의 분사, 중간에는 모호성이 없으며 오른쪽의 욕심 많은 뱀 배의 분사가 없으며 그 중 3 개는 최종 분사입니다.
이 기사는 전체 단락을 단어로 나누는 것입니다. 먼저, 단락은 구두점 마크에 따라 문장으로 나뉘어지고 각 문장은 단어를 나누기 위해 출력됩니다.
패키지 cn.nwsuaf.spilt; import java.io.bufferedReader; import java.io.fileReader; import java.io.ioexception; import java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map; 전방 및 역방향 최대 일치하는 최대 일치하는 단어 세분화 알고리즘* @Author Liu Yonglang**/public class wordspilt {/*** 스토리지 워드 세그먼테이션 사전*/개인지도 <문자열, 정수> Map = new Hashmap <String, Integer> (); / *** 최대 단어 컷 길이는 5 개의 한자입니다*/ private int max_length = 5; /** * 구성 방법에서 분사 사전을 읽고지도에 저장 * * @throws ioException */public wordspilt () IoException {bufferedReader br = new bufferedReader (새 filEReader ( "src/dict.txt")); 문자열 라인 = null; while ((line = br.readline ())! = null) {line = line.trim (); map.put (line, 0); } br.close (); } / *** 최대 단어 절단 길이 설정** @param max* 최대 단어 절단 길이* / public void setmaxlength (int max) {this.max_length = max; } / ** * 현재 최대 단어 절단 길이를 가져 오십시오. 기본값은 5 (5 중국어) * * @ @return 현재 최대 단어 절단 길이 * / public int getMaxlength () {return this.max_length; } / ** * 최대 일치하는 단어 컷 알고리즘 * * @param spiltstr * split이 split * @param lefttoright * 왼쪽에서 오른쪽으로, 오른쪽에서 왼쪽에서 왼쪽으로 나뉘어져 있습니다 * @return * / public list> spilled (string spiltstr, boolean lefttoright) {// 슬라이스 끈이 비어 있다면 (spiltstr. 널; // 양의 일치하는 분할 문자열 목록을 저장합니다. <string> leftwords = new ArrayList <string> (); // 음의 일치하는 분할 문자열 목록을 저장합니다. <string> RightWords = new ArrayList <string> (); // 슬라이싱을위한 문자열 문자열 word = null; // 단어의 길이를 취하고 최대 값으로 초기화 int wordlength = max_length; // 문자열의 현재 위치에 있습니다 int position = 0; // 문자열의 길이는 int 길이 = 0으로 처리되었습니다. // 문자열에서 여분의 공간을 제거합니다 SpiltStr = spiltstr.trim (). replaceall ( "// s+", ""); // 슬라이스 할 문자열이 슬라이스되지 않으면 루프 세분화 (길이 <spiltstr.length ()) {// 얇게 썰지 않은 문자열의 길이가 최대 값보다 작 으면 단어 자체의 길이가 단어 자체의 길이 (spiltstr.length () - 길이 <mauth_length = spiltstr.length () - 길이; // 그렇지 않으면 기본값을 사용하여 WordLength = max_length; // 전방 최대 일치 인 경우 SpiltStr의 위치에서 (LeftToright) {position = length; Word = spiltstr.substring (위치, 위치 + wordlength); } // 역 최대 일치 인 경우 SpiltStr의 끝에서 절단을 시작하십시오. else {position = spiltstr.length () - 길이; Word = spiltstr.substring (위치 - 단어 길이, 위치); } // 현재 위치에서 지정된 길이의 문자열을 자르기 시작 // word = spiltstr.substring (위치, 위치 + wordlength); // 단어 분사 사전에 문자열이 절단되지 않으면 문자를 삭제하는 경우 (! map.containskey (word)) {// 단일 단어라면 (Word.length () == 1) if (Word.length () == 1) {// word (word.matches ( "A-Za-Z0-9]) {)이 If If If If If If (Word.matches 또는 숫자를 함께 나누면 루프를 종료합니다. if (leftToright) {for (int i = spiltstr.indexof (Word, Position)+1; i <spiltstr .length (); i ++) {if ((spiltstr.charat (i)> = '0'&& spiltstr.charat (i) < ') | | | | | | | | | | | | | | | spiltstr (i) <= 'z') || } else break; }} else {// 리버스 일치 인 경우 (int i = spiltstr.indexof (단어, 위치 -1) -1; i> = 0; i-) {if ((spiltstr.charat (i)> = '0 && spiltstr.charat (i) <'|) << '|) <<'| (spiltstr.charat (i)> = 'a'&& spiltstr.charat (i) <= 'z') || if (i == 0) {StringBuffer sb = new StringBuffer (Word); Word = sb.reverse (). toString (); }} else {// 플립 작업 StringBuffer sb = new StringBuffer (Word); Word = sb.reverse (). toString (); 부서지다; } } } } 부서지다; } // 전방 최대 일치 인 경우 마지막 문자를 (LeftToright) Word = Word.SubString (0, Word.Length () -1) 인 경우 버립니다. // 그렇지 않으면 첫 번째 문자를 버립니다. else word = word.substring (1); } // 분할 문자열을 지정된 테이블에 저장하는 경우 (leftToright) leftwords.add (word); else rightwords.add (Word); // 처리 된 문자열 추가 길이 += Word.length (); } // 역 최대 일치 인 경우 테이블의 문자열을 (! leftToright) {for (int i = rightwords.size () -1; i> = 0; i-) {leftwords.add (rightwords.get (i)); }} // 슬라이싱 결과를 반환하면 왼쪽 단어를 반환합니다. } / ** * 두 세트가 평등한지 여부를 결정하십시오 * * @param list1 * set 1 * @param list2 * set 2 * @return return true, 그렇지 않으면 false * / public boolean isequal (list <string> list1, list <string> list2) {if (list1.isempty () && list2.isempty ()) false; if (list11.size ()! = list2.size ()) false를 반환합니다. for (int i = 0; i <list1.size (); i ++) {if (! list1.get (i) .equals (list2.get (i))) return false; } true를 반환합니다. } / *** 차별적 분류 모호성 함수** @param inputstr* 분할* @return 파티션 결과* / public list <string> resultword (string inputstrs) {// 파티션 결과 목록 <string> result = new arraylist <string> (); // "왼쪽 뱀"분사 결과 목록 <string> resultleft = new ArrayList <string> (); // "Medium Snake"(Divergent Part) 분사 결과 목록 <string> resultmiddle = new Arraylist <string> (); // "오른쪽 뱀"분사 결과 목록 <String> resulTright = new ArrayList <string> (); // 최대 일치하는 단어 세그먼트 화 결과 목록 <String> 왼쪽 = new ArrayList <string> (); // 역 최대 일치하는 단어 분할 결과 목록 <String> Right = New ArrayList <string> (); 왼쪽 = 유출 (inputstr, true); /*system.out.println("forward 분사 결과 : "); for (문자열 문자열 : 왼쪽) {system.out.print (String + "/"); } system.out.println ( "/n 횡단 분사 결과 :"); */ right = 유출 (inputstr, false); /*for (문자열 문자열 : 오른쪽) {System.out.print (String + "/"); } system.out.println ( "/ nboth-way word inpightle result :");*/ // // 양쪽 끝에서의 분사 스 플라이 싱이 입력 문자열의 중간에 교차했는지 여부를 결정합니다. 교차로가없는 한 (left.get (0) .length () + right.get (right.size () -1) .length () <inputstr .length ()) {// 앞쪽 및 역 단어 분사의 결과가 루프에서 점프하면 (istearal (오른쪽)이 왼쪽으로 점프하면 (rest, right, right). 부서지다; } // 앞으로 및 역 단어 분사의 결과가 다르면 분사 수가 적고 (왼쪽.size ()! = right.size ()) {resultmiddle = left.size () <right.size ()? 왼쪽 : 오른쪽; 부서지다; } // 위의 조건이 충족되지 않으면 "뱀"알고리즘을 구현하십시오. // "왼쪽 욕심 많은 뱀"을 전진 단어의 첫 번째 단어를 전진 단어 분사 결과 resultleft.add (left.get (0)); // "Right Greedy Snake"를 반대 단어 분사 결과 resultright.add (right.get (right.size () -1))의 마지막 단어를 먹게하십시오. // "뱀"으로 먹는 단어를 제거합니다. inputstr = inputstr.substring (left.get (0) .length ()); inputstr = inputstr.substring (0, inputstr.length () - right.get (right.size () -1) .length ()); // 간섭을 방지하기 위해 이전의 양수 및 역 단어 세분화 결과를 정리하십시오 .Clear (); right.clear (); // 왼쪽으로 이식되지 않은 문자열에 대한 분사를 시작합니다 = spiled (inputstr, true); 오른쪽 = 유출 (inputstr, false); } // 루프의 끝은 분사가 모호하지 않거나 "욕심 많은 뱀"이 양쪽 끝에서 교차로로 먹는다는 것을 의미합니다. // 교차로에서 분사라는 단어라면 다음 판단이 이루어져야합니다 : // 중간 상호 작용이 겹치는 경우 : // 마지막 방향의 길이 + 마지막 길이의 길이는 끈의 길이에 직접 입력하는 경우 : // (left.get (0) .length () + right.get (right.size () -1) .length ()> inputstr .length ()) resultmiddle = left; // 중간 교차로가 교차하는 경우 음식을 가져 가면 겹치지 않습니다. // 전방 방향의 첫 번째 분사 + 역 방향의 마지막 분사 길이 = 문자열의 총 길이를 입력하면 (왼쪽) (0) .length () .length (right.get.get ()) = inputstr () inputstr () inputstr. resultmiddle.add (left.get (0)); resultmiddle.add (right.get (right.size () -1)); } // (문자열 문자열 : resultleft) {result.add (string); } for (문자열 문자열 : resultMiddle) {result.add (string); } // "Right Greedy Snake"에 저장된 분사는 (int i = resultright.size () -1; i> = 0; i-) {result.add (resulTright.get (i)); } 반환 결과; } / ** * 단락을 여러 문장으로 나누고 단어 분할을 개별적으로 수행하십시오 * * @param inputstr *이 단락의 단락 * / public list <string> resultspilt (string inputstr) {// 최종 단어 세그먼트 목록 <string> 결과 = newrayList <문자열을 저장하는 데 사용됩니다. // 구두점이 발생하면 여러 문장으로 나뉩니다. String regex = "[,.;!?]"; 문자열 [] st = inputstr.split (regex); // 각 문장의 분사 결과를 최종 분사 결과 (String stri : st) {list <string> list = resultword (stri); result.addall (목록); } 반환 결과; } public static void main (string [] args) {// 예 : 가서 주택 가격이 비싸는 지 확인하십시오. 탁구 경매 스캐너 입력 = 새 스캐너 (System.In); 문자열 str = input.nextline (); WordSpilt WordSpilt = null; try {wordspilt = new WordsPilt (); } catch (ioexception e) {e.printstacktrace (); } list <string> list = WordSpilt.ResultWord (str); for (문자열 문자열 : list) {system.out.print (String + "/"); }}}src/dict.txt는 사전 파일이며 설정은 다음과 같습니다.
wulin.com 스크립트 다운로드 스크립트 튜토리얼 자료 다운로드에 오신 것을 환영합니다
작업 결과는 다음과 같습니다.
Java 알고리즘에 대한 자세한 내용은이 사이트에 관심이있는 독자들이 주제를 볼 수 있습니다. "Java 데이터 구조 및 알고리즘 자습서", "Java Operation Dom Node Tips 요약", "Java 파일 및 디렉토리 작동 팁 요약"및 "Java Cache Operation Tips의 요약"을 볼 수 있습니다.
이 기사가 모든 사람의 Java 프로그래밍에 도움이되기를 바랍니다.