最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)簡易的分詞器功能

 更新時間:2021年06月15日 16:24:58   作者:kicinio  
搜索功能是具備數(shù)據(jù)庫功能的系統(tǒng)的一大重要特性和功能,生活中常見的搜索功能基本上都具備了分詞搜索功能.然而ES功能固然強大,但對于學生或小項目而言整合起來太費人力物力,若是寫個分詞器就會使項目錦上添花,使其不僅僅是只能單關鍵詞搜索的系統(tǒng),需要的朋友可以參考下

業(yè)務需求:

生活中常見的搜索功能大概可分為以下幾類:

  • 單關鍵詞。如“Notebook”
  • 雙關鍵詞加空格。如“Super Notebook”
  • 多關鍵詞加多空格。如“Intel Super Notebook”

當然,還有四甚至五關鍵詞,這些搜索場景在生活中可以用罕見來形容,不在我們的討論范圍。我們今天就以上三種生活中最常見的搜索形式進行探討分析。業(yè)務需求也很簡單,假設我們要完成一個搜索功能,業(yè)務層、持久層、控制層不在我們討論的范圍,僅討論分詞功能如何實現(xiàn)。

分析:

假設用戶鍵入的搜索內(nèi)容為以下內(nèi)容:

Intel Super Notebook

我們可以利用Java中String強大而豐富的方法來慢慢拼湊一個小算法來達到目的。String中大多數(shù)方法的參數(shù)和返回值都與下標相關,那么,分析上述語句的下標,我們可發(fā)現(xiàn)如下內(nèi)容:

在這里插入圖片描述

上述內(nèi)容紅色是我們分詞的關鍵內(nèi)容。對于一個語句而言(不是語言學上通俗的語句,因為該句沒有主謂賓),重要的就是各單詞或詞組的首字母下標與該單詞或詞組后面最近一個空格。我們發(fā)現(xiàn),Intel這個單詞首字母下標為0,距離該單詞后面最近的一個空格下標為5;Super首字母下標為距離該單詞前面最近的一個空格的下標加1,也就是6;Notebook首字母下標為距離該單詞前面最近的一個空格的下標加1,也就是12;最后就是該語句的尾下標,也就是19。

當然,實際情況會有用戶多輸入了兩個甚至三個空格在某兩個單詞之間,例如如下形式:

Intel  Super  Notebook

(注意這里的空格為每個單詞之間為2個)

這個問題很容易解決,我們把兩個或三個空格替換為一個空格即可(為什么不是四個或者更多?因為現(xiàn)實情況是用戶不太可能在各個單詞之間連按多個空格),如下:

sentence = sentence.replace("  ", " ");
sentence = sentence.replace("   ", " ");

這樣以來語句中就只存在單個空格了。

經(jīng)過分析我們得知,若想對一個語句進行分詞,就必須知道各個單詞的起始下標才行。起始下標可以由空格的下標得知,那我們該如何得知空格的下標?

很簡單,我們寫個方法,通過迭代語句的每個單詞,判斷其是否存在空格即可。方法如下:

private int firstPosition(){
	int first = 0;
	for(int i = 0; i < sentence.length(); i++){
		if(String.valueOf(sentence.charAt(i)).equals(" ")){
			first = i;
			return first;
		}	
	}
	return first;
}

這個方法的作用是判斷一個語句中第一個空格的位置。既然有第一個了,肯定要有第二個了。要注意第一個內(nèi)容是從0開始進行迭代,而第二個空格的判斷方法要從第一個空格的位置加1開始,否則迭代的剛好還是第一個空格的位置。內(nèi)容如下:

private int secondPosition(){
		int second = 0;
		for(int i = (firstPosition() + 1); i < sentence.length(); i++){
			if(String.valueOf(sentence.charAt(i)).equals(" ")){
				second = i;
				return second;
			}	
		}
		return second;
	}

第三個為什么不迭代?因為第三個單詞之后就沒有空格了,就到結尾了。

找出每個空格的下標索引后,我們還需知道語句中含有多少個空格,是沒有,還是1個或2個(連續(xù)的重復空格在上文已經(jīng)被替換為單個空格了)。方法如下:

private int countBlank(String s){
	// Store single blank signal.
	int amount = 0;

	// If s contains single blank signal, and it will increse amount's value of 1 every loop times.
	for(int i = 0; i < s.length(); i++){
		if(String.valueOf(sentence.charAt(i)).equals(" ")){
			amount++;
		}
	}
	return amount;
}

拿到了空格的總個數(shù)及每個空格的下標,我們就可以寫個方法進行分割了。由于我是采用了泛型集合作為數(shù)據(jù)源,這里的方法返回類型就為void。

我們先假設輸入的僅有以下內(nèi)容:

Intel

輸入的僅有一個詞組。我們先判斷其空格的個數(shù),發(fā)現(xiàn)為0,那么也不用進行什么操作了,直接添加其作為集合的數(shù)據(jù)。

public void divide(){
		// Record every single blank signal's position.
		int position1 = firstPosition();
		int position2 = secondPosition();
		
		if(sentence.contains(" ")){

		} else{
        	words.add(sentence);
     	}
		
	}

現(xiàn)在情況變?yōu)檩斎氲膬?nèi)容如下:

Intel Super

我們知道了這個語句共有一個空格,下標為5,長度為11,那可以這樣判斷:是否包含空格,如果是,那就判斷其空格數(shù)是否大于等于0,如果為真,就添加到數(shù)據(jù)源。接著判斷其空格數(shù)是否大于等于1,如果真,進入下一層判斷其空格數(shù)是否大于等于1其小于2,如果真,就添加到數(shù)據(jù)源。內(nèi)容如下:

public void divide(){
		// Record every single blank signal's position.
		int position1 = firstPosition();
		int position2 = secondPosition();
		
		if(sentence.contains(" ")){
			int blankAmount = countBlank(sentence);
			if (blankAmount >= 0) {
				words.add(sentence.substring(0, position1));
				if (blankAmount >= 1) {
					if(blankAmount >= 1 && blankAmount < 2)));
						words.add(sentence.substring(position1, sentence.length()));
					} else {

					}
	
				} 
				
			}
		} else{
        	words.add(sentence);
     	}
	}

下面就是較為全面的情況了:

Intel Super Notebook

我們判斷完兩個情況就看第三個情況。第三個單詞其獲取是通過第二個空格下標與語句長度得來。但第二個單詞就要改為第一個空格下標加1與第二個空格下標加1了。那么至此分割方法也就完成了:

public String divide(){
	// Record every single blank signal's position.
	int position1 = firstPosition();
	int position2 = secondPosition();
	
	if(sentence.contains(" ")){
		int blankAmount = countBlank(sentence);
		if (blankAmount >= 0) {
			words.add(sentence.substring(0, position1));
			if (blankAmount >= 1) {
				if(blankAmount >= 1 && blankAmount < 2){
					words.add(sentence.substring(position1, sentence.length()));
				} else {
					words.add(sentence.substring(position1, position2));
					if (blankAmount >= 2) {
						words.add(sentence.substring(position2, sentence.length()));
					}
				}

			} 
			
		}
	} else{
        	words.add(sentence);
     	}
	
}

測試:

Intel Super Notebook

SIZE:3
POSITION(0): Intel
POSITION(1): Super
POSITION(2): Notebook

Intel   Super   Notebook

(注這里有重復且連續(xù)的空格)
SIZE:3
POSITION(0): Intel
POSITION(1): Super
POSITION(2): Notebook

英特爾 超級  筆記本

SIZE:3
POSITION(0): 英特爾
POSITION(1): 超級
POSITION(2): 筆記本

華為

SIZE:1
POSITION(0): 華為

完整代碼:

class DivideWord{
	
	private String sentence;
	private List<String> words = new ArrayList<String>();

	public DivideWord(String sentence) {
		// Replace two or three blank signal that connected into single blank signal.
		sentence = sentence.replace("  ", " ");
		sentence = sentence.replace("   ", " ");
		this.sentence = sentence;
	}
	
	private int countBlank(String s){
		// Store single blank signal.
		int amount = 0;

		// If s contains single blank signal, and it will increse amount's value of 1 every loop times.
		for(int i = 0; i < s.length(); i++){
			if(String.valueOf(sentence.charAt(i)).equals(" ")){
				amount++;
			}
		}
		return amount;
	}
	
	private int firstPosition(){
		int first = 0;
		for(int i = 0; i < sentence.length(); i++){
			if(String.valueOf(sentence.charAt(i)).equals(" ")){
				first = i;
				return first;
			}	
		}
		return first;
	}
	
	private int secondPosition(){
		int second = 0;
		for(int i = (firstPosition() + 1); i < sentence.length(); i++){
			if(String.valueOf(sentence.charAt(i)).equals(" ")){
				second = i;
				return second;
			}	
		}
		return second;
	}
	
	public String divide(){
		// Record every single blank signal's position.
		int position1 = firstPosition();
		int position2 = secondPosition();
		
		if(sentence.contains(" ")){
			int blankAmount = countBlank(sentence);
			if (blankAmount >= 0) {
				words.add(sentence.substring(0, position1));
				if (blankAmount >= 1) {
					if(blankAmount >= 1 && blankAmount < 2){
						words.add(sentence.substring(position1, sentence.length()));
					} else {
						words.add(sentence.substring(position1, position2));
						if (blankAmount >= 2) {
							words.add(sentence.substring(position2, sentence.length()));
						}
					}
	
				} 
				
			}
		} else{
        	words.add(sentence);
     	}
	}
	
	public int getSize(){
		return words.size();
	}
	
	public String getWord(int position){
		return words.get(position);
	}
}

public class DateGet {
	public static void main(String[] args){
		DivideWord divideWord = new DivideWord("英特爾");
		divideWord.divide();
		System.out.println("SIZE:" + divideWord.getSize());
		System.out.println("POSITION :" + divideWord.getWord(0));
		
	}
}

到此這篇關于Java實現(xiàn)簡易的分詞器功能的文章就介紹到這了,更多相關Java分詞器功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java中使用RediSearch實現(xiàn)高效的數(shù)據(jù)檢索功能

    Java中使用RediSearch實現(xiàn)高效的數(shù)據(jù)檢索功能

    RediSearch是一款構建在Redis上的搜索引擎,它為Redis數(shù)據(jù)庫提供了全文搜索、排序、過濾和聚合等高級查詢功能,本文將介紹如何在Java應用中集成并使用RediSearch,以實現(xiàn)高效的數(shù)據(jù)檢索功能,感興趣的朋友跟著小編一起來看看吧
    2024-05-05
  • Springboot項目通過redis實現(xiàn)接口的冪等性

    Springboot項目通過redis實現(xiàn)接口的冪等性

    這篇文章主要為大家介紹了Springboot項目通過redis實現(xiàn)接口的冪等性,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Java實現(xiàn)的最大匹配分詞算法詳解

    Java實現(xiàn)的最大匹配分詞算法詳解

    這篇文章主要介紹了Java實現(xiàn)的最大匹配分詞算法,簡單說明了最大匹配分詞算法的原理并結合具體實例形式最大匹配分詞算法的實現(xiàn)方法與相關注意事項,需要的朋友可以參考下
    2017-09-09
  • Java中Array、List、Map相互轉(zhuǎn)換的方法詳解

    Java中Array、List、Map相互轉(zhuǎn)換的方法詳解

    這篇文章主要介紹了Java中Array、List、Map相互轉(zhuǎn)換的方法詳解,在實際項目開發(fā)中或者一些算法面試題目中經(jīng)常需要用到Java中這三種類型的相互轉(zhuǎn)換,比如對于一個整型數(shù)組中尋找一個整數(shù)與所給的一個整數(shù)值相同,需要的朋友可以參考下
    2023-08-08
  • JAVA加密算法數(shù)字簽名實現(xiàn)原理詳解

    JAVA加密算法數(shù)字簽名實現(xiàn)原理詳解

    這篇文章主要介紹了JAVA加密算法數(shù)字簽名實現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • idea中加入git版本控制的方法及步驟詳解

    idea中加入git版本控制的方法及步驟詳解

    在idea中加入git版本控制,方便團隊中多人協(xié)同開發(fā),項目可以同時方便進行管理和迭代。下面就是idea中加入git 的方法和步驟,感興趣的朋友一起看看吧
    2021-09-09
  • SpringBoot版本升級容易遇到的一些問題

    SpringBoot版本升級容易遇到的一些問題

    由于項目需求,需要將nacos 1.4.6版本升級到2.x版本,由此引發(fā)的springboot、springcloud、springcloud Alibaba一系列版本變更,本文給大家總結一下SpringBoot版本升級容易遇到的一些問題,需要的朋友可以參考下
    2023-12-12
  • java objectUtils 使用可能會出現(xiàn)的問題

    java objectUtils 使用可能會出現(xiàn)的問題

    這篇文章主要介紹了java objectUtils 使用可能會出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java文檔注釋用法+JavaDoc的使用說明

    Java文檔注釋用法+JavaDoc的使用說明

    這篇文章主要介紹了Java文檔注釋用法+JavaDoc的使用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java如何實現(xiàn)定時任務

    Java如何實現(xiàn)定時任務

    這篇文章主要介紹了Java如何實現(xiàn)定時任務,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07

最新評論

鄱阳县| 枝江市| 柳江县| 海南省| 延川县| 金山区| 驻马店市| 兴山县| 营山县| 高邑县| 永吉县| 连州市| 祁阳县| 蕲春县| 泸州市| 万宁市| 新乡市| 内黄县| 天祝| 外汇| 日土县| 普定县| 安塞县| 方山县| 乌鲁木齐市| 平湖市| 浑源县| 保亭| 五指山市| 徐州市| 峨山| 镇坪县| 衡山县| 石台县| 万安县| 彰化市| 柳江县| 天全县| 阳朔县| 曲松县| 阜平县|