行业知识
如何将编辑距离算法运用到根据标签进行用户智能匹配的业务场景中
2026-11-07 10:56:43
来源:互联网转载
如何将编辑距离算法运用到根据标签进行用户智能匹配的业务场景中
-
什么���最小编辑距离(可以看看下面这位博主的详细介绍)
()编辑距离算法详细介绍
-
将代码在java测试类里面进行测试
()package com.way.threes_company_backend.service;import com.way.threes_company_backend.utils.AlgoUtils;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;import java.util.Arrays;import java.util.List;@SpringBootTestpublic class AlgoUtilsTest { public int minDistance(String word1, String word2){ int n = word1.length(); int m = word2.length(); if(n * m == 0) return n + m; int[][] d = new int[n + 1][m + 1]; for (int i = 0; i -
这里我们还需要给代码做一些优化,因为我们的用户标签是这种格式[“java”,“男”, “大二”] 是列表格式,所以我们需要进行稍微的更改源代码
public static int minDistance(List listTag1, List listTag2) { int n = listTag1.size(); int m = listTag2.size(); if (n * m == 0) return n + m; int[][] d = new int[n + 1][m + 1]; for (int i = 0; i -
应用场景:我们需要在用户首页进行用户匹配之后推荐出标签最相近的5位用户,然后将信息展示到首页,同时也可以展示另外几条不太匹配的用户信息(随机推荐)
实现步骤
-
获取当前登录用户的id,根据id查询出当前登录用户的tags(标签数据)
-
创建一个查询对象,条件是只查询id和tags并且tags不为空的数据(能够提升查询速度)查询所有用户的tags
-
使用pair创建一个临时的列表存储用户的(id, tags) 和 编辑距离的值(得分)
-
遍历上面查到的所有用户的tags然后调用封装的utils里面的编辑距离算法和当前用户的tags进行计算,然后将结果存储到pairList里面
-
使用集合的stream流方法进行pairList的数据排序,并且只取num个数据(top num)
-
然后将top num的数据里面的id单独提取出来(因为我们最后需要返回这些id对应的详细的用户信息,然后展示到前端
-
创建一个查询对象,条件是用户的id在这个idList里面的用户信息 使用一个map集合进行存储 Map
-
这里的map会将我们需要的top num的顺序进行打乱,所以最后我们还需要创建一个list集合 + for循环遍历前面的idList取出对应的Map里面的用户数据 才是正确的顺序
代码演示
@Override public List matchUsers(long num, User loginUser) { final int userId = loginUser.getId(); // 01. 创建一个查询对象 只查询id 和 tags 并且过滤掉空的数据 这样可以提升查询的速度(减少了不需要的字段的查询且过滤了空的数据) QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.select("id", "tags"); queryWrapper.isNotNull("tags"); List list = this.list(queryWrapper); // 02. 获取到当前登录用户的tags 它是作为编辑距离算法的根本 将所有的用户的tags和当前登录用户的tag进行比较找出最相似的几个用户即可 (原理) String tags = loginUser.getTags(); // 03. 使用gson将json格式序列化为一个列表形式 因为存储在mysql里面的数据是json格式 Gson gson = new Gson(); List loginUserTagList = gson.fromJson(tags, new TypeToken() { }.getType()); // 04. 使用pair来临时存储用户信息 和相似度分数 List pairList = new ArrayList(); // 05. for循环依次遍历所有用户信息来计算相似度 for (int i = 0; i (int) (a.getValue() - b.getValue())) .limit(num) .collect(Collectors.toList()); // 07. 将pair里面的id单独提取出来 目的是为了我们能够获取到所有的用户信息然后再打印出来 使用map能进行一个新的映射 List idList = topUserPairList.stream().map(a -> a.getKey().getId()).collect(Collectors.toList()); // 08. 创建查询对象,查询当前id在id列表里面的用户数据 QueryWrapper userQueryWrapper = new QueryWrapper(); // 查询当前id在这个id列表里面的用户数据 userQueryWrapper.in("id", idList); // 09. 将查询出来的结果使用一个map集合进行存储 userid1 -> user1 userid2 -> user2... Map userIdUserListMap = this.list(userQueryWrapper) .stream() .map(user -> getSafetyUser(user)) // 用户信息脱敏 .collect(Collectors.groupingBy(User::getId)); // 10. 创建一个新的集合对象来将顺序进行规整 需要返回的顺序 1 2 3 前面map的顺序 1 3 2 List finalUserList = new ArrayList(); // 使用for循环遍历前面的正确顺序的idList 然后将map里面的数据调用get方法,传递id且获取一个 最后追加到list里面返回即可 for (Integer integerUserId : idList) { finalUserList.add(userIdUserListMap.get(integerUserId).get(0)); } return finalUserList; }最后前端调用接口就可以返回和自己标签匹配度top num的用户详细数据了
-