Levenshtein 距离,又称编辑距离,在模糊筛选中的应用(接上部分上传功能,批量查询)

因为项目做一个一个批量查询,当后台将上传的Excel表格解析并返回到前台的input搜索框后,点击查询寻
$table.search()进入到后台,因为项目需要,其需要进行一个模糊查询,按匹配度,查出相关的内容,匹配度100%,只查出一条,不足的按匹配度从高到低,查出5条。匹配度为0的就查不出。
现在看后台:
因为前台写了一个查询和批量查询按钮,所以这里做了一个判断。因为查询条件拿的是form表单的值,所以要进行判断。

/**
	 * 查询企业背景-企业基本列表
	 */
	@RequiresPermissions("system:tycBaseinfo:list")
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(TycBaseinfo tycBaseinfo)
	{
		/*startPage();*/
		List <TycBaseinfo> listAll= new ArrayList<>();
		String selectName = tycBaseinfo.getName();
		String nameAll = tycBaseinfo.getNameArr();
		//批量查询
		if((!("").equals(nameAll)&&nameAll!=null)&&(("").equals(selectName)||selectName==null)){
			return getDataTable(tycBaseinfoService.selectTycBaseinfoSearchList(tycBaseinfo));
		}else {
			//单项查询
			tycBaseinfo.setNameArr("");
			return getDataTable(tycBaseinfoService.selectTycBaseinfoList(tycBaseinfo));
		}


	}

这里主要看server层的逻辑代码:
tycBaseinfoService.selectTycBaseinfoSearchList(tycBaseinfo)

进入servers层

public List<TycBaseinfo> selectTycBaseinfoSearchList(TycBaseinfo tycBaseinfo)
	{
		List <TycBaseinfo> listAll= new ArrayList<>();
		//存放匹配度100%list
		List <TycBaseinfo> listOnly= new ArrayList<>();
		//存放匹配度不是100%list
		List <TycBaseinfo> listMany= new ArrayList<>();
		String nameAll = tycBaseinfo.getNameArr();
			String[] nameArr = nameAll.split(",");
			List<String> factoryNameList=new ArrayList<String>(Arrays.asList(nameArr));
			for(int i=0;i<factoryNameList.size(); i++) {
				TycBaseinfo tycBaseinfo1 = new TycBaseinfo();
				List<TycBaseinfo> list = tycBaseinfoMapper.selectTycBaseinfoList(tycBaseinfo1);
				//对每个查询条件第一个查询出来的数据,selectName进行赋值(等价于前台分组)
				//拿到当前的查询条件,进行比对。查出匹配度最高的五条记录
				//进行分组查询,需要将保存企业命名的nameList遍历查询
				String str1 = factoryNameList.get(i);
				//如果查询条件是空,或是null,则默认查出所有数据
				if(("").equals(str1)||str1==null){

				}else{
					list = levenshtein(str1,list);
					if(list.size()==1){
						for (int j = 0; j < list.size(); j++) {
							if (j == 0) {
								list.get(j).setSelectName(factoryNameList.get(i));
							} else {
								list.get(j).setSelectName("");
							}
						}
						//如果是匹配度100%,就一条数据,就保存到listOnly
						listOnly.addAll(list);
					}else{
						for (int j = 0; j < list.size(); j++) {
							if (j == 0) {
								list.get(j).setSelectName(factoryNameList.get(i));
							} else {
								list.get(j).setSelectName("");
							}
						}
						//如果是匹配度不是100%,就有5或以下条数据,就保存到listMany
						listMany.addAll(list);
					}
				}
			}
		listAll.addAll(listOnly);
		listAll.addAll(listMany);
			return listAll;
	}

因为前台传来的NameArr是一大串字符串,所以采用
String[] nameArr = nameAll.split(",");进行分割,存到数组中
然后将其转为list
List factoryNameList=new ArrayList(Arrays.asList(nameArr));

查出所以数据:
List list = tycBaseinfoMapper.selectTycBaseinfoList(tycBaseinfo1);

调用编辑算法
list = levenshtein(str1,list);

编辑距离算法

public List<TycBaseinfo> levenshtein(String str1,List<TycBaseinfo> list) {
		//保存相似度
	/*	List<Float> similaritylist = new ArrayList();*/
		//listFive用于保存匹配对最高的五条记录
		List<TycBaseinfo> listFive = new ArrayList<>() ;
		//保存相似度最大的值
		float similarityFirst = (float) 0;
		float similaritySecond = (float) 0;
		float similarityThird = (float) 0;
		float similarityFourth = (float) 0;
		float similarityFifth = (float) 0;
		//保存相似度最大的那条记录的list的i值
		int first = 0;
		int second = 0;
		int third = 0;
		int fourth = 0;
		int fifth = 0;

		//计算两个字符串的长度。
     	int len1 = str1.length();
     	for(int k =0;k<list.size();k++){
			String str2 = list.get(k).getName();
			int len2 = str2.length();
			//建立上面说的数组,比字符长度大一个空间
			int[][] dif = new int[len1 + 1][len2 + 1];
			//赋初值,步骤B。
			for (int a = 0; a <= len1; a++) {
				dif[a][0] = a;
			}
			for (int a = 0; a <= len2; a++) {
				dif[0][a] = a;
			}
			//计算两个字符是否一样,计算左上的值
			int temp;
			for (int i = 1; i <= len1; i++) {
				for (int j = 1; j <= len2; j++) {
					if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
						temp = 0;
					} else {
						temp = 1;
					}
					//差异步骤,取三个值中最小的
					dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1,
							dif[i - 1][j] + 1);
				}
			}

			/*System.out.println("字符串\""+str1+"\"与\""+str2+"\"的比较");
			//取数组右下角的值,同样不同位置代表不同字符串的比较
			System.out.println("差异步骤:"+dif[len1][len2]);
			//计算相似度*/
			float similarity =1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length());
			/*System.out.println("相似度:"+similarity);*/
			//取相似度最高的那条记录
			 if(similarityFirst<=similarity){
				 similarityFirst = similarity;
				 first= k;
			 }
			//取相似度第二的那条记录
			if(similarity<similarityFirst&&similaritySecond<=similarity){
				similaritySecond = similarity;
				second= k;
			}
			//取相似度第三的那条记录
			if(similarity<similaritySecond&&similarityThird<=similarity){
				similarityThird = similarity;
				third= k;
			}
			//取相似度第四的那条记录
			if(similarity<similarityThird&&similarityFourth<=similarity){
				similarityFourth = similarity;
				fourth= k;
			}
			//取相似度第五的那条记录
			if(similarity<similarityFourth&&similarityFifth<=similarity){
				similarityFifth = similarity;
				fifth= k;
			}
		}
		if(similarityFirst ==1.00){
			listFive.add(list.get(first));
		}else if(similarityFirst == 0.00){

		}else{
			listFive.add(list.get(first));
			if(similaritySecond != 0.00){
				listFive.add(list.get(second));
			}
			if(similarityThird != 0.00){
				listFive.add(list.get(third));
				}
			if(similarityFourth != 0.00){
				listFive.add(list.get(fourth));
			}
			if(similarityFifth != 0.00){
				listFive.add(list.get(fifth));
			}

		}
     	return listFive;
		}

		//得到最小值
	private static int min(int... is) {
		int min = Integer.MAX_VALUE;
		for (int i : is) {
			if (min > i) {
				min = i;
			}
		}
		return min;
	}

listAll.addAll(listOnly);
listAll.addAll(listMany);
listOnly是保存匹配度100%的信息
listMany是保存匹配度不为100%的信息。
最后进行拼接,保存到一个list中
最后,和上面的上传功能整体的一个页面是这样的
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值