亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

業(yè)務(wù)需求:

生活中常見(jiàn)的搜索功能大概可分為以下幾類(lèi):

  • 單關(guān)鍵詞。如“Notebook”
  • 雙關(guān)鍵詞加空格。如“Super Notebook”
  • 多關(guān)鍵詞加多空格。如“Intel Super Notebook”

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

分析:

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

Intel Super Notebook

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

在這里插入圖片描述

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

當(dāng)然,實(shí)際情況會(huì)有用戶(hù)多輸入了兩個(gè)甚至三個(gè)空格在某兩個(gè)單詞之間,例如如下形式:

Intel  Super  Notebook

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

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

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

這樣以來(lái)語(yǔ)句中就只存在單個(gè)空格了。

經(jīng)過(guò)分析我們得知,若想對(duì)一個(gè)語(yǔ)句進(jìn)行分詞,就必須知道各個(gè)單詞的起始下標(biāo)才行。起始下標(biāo)可以由空格的下標(biāo)得知,那我們?cè)撊绾蔚弥崭竦南聵?biāo)?

很簡(jiǎn)單,我們寫(xiě)個(gè)方法,通過(guò)迭代語(yǔ)句的每個(gè)單詞,判斷其是否存在空格即可。方法如下:

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

這個(gè)方法的作用是判斷一個(gè)語(yǔ)句中第一個(gè)空格的位置。既然有第一個(gè)了,肯定要有第二個(gè)了。要注意第一個(gè)內(nèi)容是從0開(kāi)始進(jìn)行迭代,而第二個(gè)空格的判斷方法要從第一個(gè)空格的位置加1開(kāi)始,否則迭代的剛好還是第一個(gè)空格的位置。內(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;
	}

第三個(gè)為什么不迭代?因?yàn)榈谌齻€(gè)單詞之后就沒(méi)有空格了,就到結(jié)尾了。

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

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

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

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

Intel

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

我們知道了這個(gè)語(yǔ)句共有一個(gè)空格,下標(biāo)為5,長(zhǎng)度為11,那可以這樣判斷:是否包含空格,如果是,那就判斷其空格數(shù)是否大于等于0,如果為真,就添加到數(shù)據(jù)源。接著判斷其空格數(shù)是否大于等于1,如果真,進(jìn)入下一層判斷其空格數(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

我們判斷完兩個(gè)情況就看第三個(gè)情況。第三個(gè)單詞其獲取是通過(guò)第二個(gè)空格下標(biāo)與語(yǔ)句長(zhǎng)度得來(lái)。但第二個(gè)單詞就要改為第一個(gè)空格下標(biāo)加1與第二個(gè)空格下標(biāo)加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);
     	}
	
}

測(cè)試:

Intel Super Notebook

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

Intel   Super   Notebook

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

英特爾 超級(jí)  筆記本

SIZE:3
POSITION(0): 英特爾
POSITION(1): 超級(jí)
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));
		
	}
}

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

相關(guān)文章

  • AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀

    AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀

    這篇文章主要為大家介紹了AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Web服務(wù)器實(shí)例解析

    java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Web服務(wù)器實(shí)例解析

    這篇文章主要介紹了java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Web服務(wù)器實(shí)例解析,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 一篇文章看懂Java字符串操作

    一篇文章看懂Java字符串操作

    String是Java中的類(lèi),它提供一些預(yù)定義的方法,這些方法使基于字符串的問(wèn)題解決方案更加容易,下面這篇文章主要給大家介紹了關(guān)于Java字符串操作的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 解決FeignClient重試機(jī)制造成的接口冪等性

    解決FeignClient重試機(jī)制造成的接口冪等性

    這篇文章主要介紹了解決FeignClient重試機(jī)制造成的接口冪等性問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring事務(wù)aftercommit原理及實(shí)踐

    Spring事務(wù)aftercommit原理及實(shí)踐

    這篇文章主要為大家介紹了Spring事務(wù)aftercommit原理及實(shí)踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 六個(gè)Java集合使用時(shí)需要注意的事項(xiàng)

    六個(gè)Java集合使用時(shí)需要注意的事項(xiàng)

    這篇文章主要為大家詳細(xì)介紹了六個(gè)Java集合使用時(shí)需要注意的事項(xiàng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)java有一定的幫助,需要的可以參考一下
    2023-01-01
  • 全排列算法-遞歸與字典序的實(shí)現(xiàn)方法(Java)

    全排列算法-遞歸與字典序的實(shí)現(xiàn)方法(Java)

    下面小編就為大家?guī)?lái)一篇全排列算法-遞歸與字典序的實(shí)現(xiàn)方法(Java) 。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • Java中自動(dòng)生成構(gòu)造方法詳解

    Java中自動(dòng)生成構(gòu)造方法詳解

    這篇文章主要介紹了Java中自動(dòng)生成構(gòu)造方法詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Spring Bean配置方式總結(jié)

    Spring Bean配置方式總結(jié)

    定義Spring Bcan的3種方式分別是:基于XML 的方式配置、基于注解掃播方式配置、基于元數(shù)據(jù)類(lèi)的配置,本文就通過(guò)代碼示例給大家詳細(xì)講講這三種配置方式,需要的朋友可以參考下
    2023-12-12
  • Java簡(jiǎn)單冒泡排序示例解析

    Java簡(jiǎn)單冒泡排序示例解析

    這篇文章主要介紹了Java簡(jiǎn)單冒泡排序示例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評(píng)論