当前位置: 首页 > news >正文

字符串进行前缀匹配

问题

工作中接到这样一个需求
货品编号的前缀是由分类的编号组成的, 用户输入货品编号的时候自动回显出货品的分类.
而 货品的分类编号是不规则的
如: 0401,020508,27800101
每一个编号的长度都是不同的, 不过好在是相同数组开头的编号长度都是统一的.
所以不免有些人会冒出写死匹配的想法. 但是这也太low了.
经过不懈的尝试和努力终于找到了两种解决方案.

第一种

得到货品编号的时候, 以步长为1 从后向前依次截取字符串, 将截取后的字符串去分类编号中进行匹配,如匹配到了则将分类信息返回, 如匹配不到则继续进行匹配,直到匹配到为止;

代码示例

	public GoodsCategoryEntity getByGoodsIdnumber(String goodsIdnumber) {
		// 获取所有的分类信息
		List<GoodsCategoryEntity> list = this.list();
		// 以编码为key, 转换成map集合
		Map<String, GoodsCategoryEntity> goodsCategoryMap = list.stream().collect(Collectors.toMap(GoodsCategoryEntity::getIdnumber, Function.identity()));
		// 调用编码截取匹配方法
		GoodsCategoryEntity goodsGategory = getGoodsGategory(goodsIdnumber, goodsCategoryMap);
		return goodsGategory;
	}

	//从货品编码中匹配出货品分类编码
	private GoodsCategoryEntity getGoodsGategory(String goodsIdnumber,  Map<String, GoodsCategoryEntity> goodsCategoryMap) {
		if (Func.isBlank(goodsIdnumber)) {
			return new GoodsCategoryEntity();
		}
		// 进行字符串截取
		String substring = goodsIdnumber.substring(0, goodsIdnumber.length() - 1);
		// 如果截取出的编码匹配到了分类信息则返回, 没匹配到则进行递归继续匹配
		return Func.isEmpty(goodsCategoryMap.get(substring))?getGoodsGategory(substring, goodsCategoryMap):goodsCategoryMap.get(substring);
		
	}

第二种

其实思想同上述方法差不多,只不过上述方法是从后往前匹配, 该方法是从前往后匹配;
从前往后就要比从后往前多考虑一些, 因为分类编码存在父子级关系
比如: 04 和 0401 和 040101
所以不能匹配到一个就结束.

上代码

# 首先要创建一个前缀树

public class Trie implements Serializable {

	private static final long serialVersionUID = 1L;

    public static class Node{
		public Map<Character, Node> children = new HashMap<>();
    }

	public Node root = new Node();
    public Trie() {

    }
	// 将元素填入前缀字典中
    public void insert(String word) {
        Node pre = this.root;
        for(char c: word.toCharArray()){
            Node node = pre.children.get(c);
            if(node == null){
                node = new Node();
                pre.children.put(c, node);
            }
            pre = node;
        }
    }
	// 查询前缀并返回前缀
    public String search(String word) {
        Node pre = this.root;
		String str = "";
        for(char c: word.toCharArray()){
            Node node = pre.children.get(c);
            if(node == null) return str;
			str = str + c;
            pre = node;
        }
        return str;
    }
}
	public GoodsCategoryEntity getByGoodsIdnumber(String goodsIdnumber) {
		// 获取所有的分类信息
		List<GoodsCategoryEntity> list = this.list(Wrappers.lambdaQuery(GoodsCategoryEntity.class).select(GoodsCategoryEntity::getIdnumber));
		// 填充好前赘树
		Trie  trie = new Trie();
		for (GoodsCategoryEntity category : list) {
			trie_map.insert(string);	
		}
		# 以上步骤可以提前预制好, 并将trie对象序列化存在缓存中, 在使用时直接从缓存中获取 trie 对象

		// 进行编码匹配
		String number = trie_map.search(goodsIdnumber);
		// 通过编码获取分类对象
		GoodsCategoryEntity entity = this.getOne(Wrappers.lambdaQuery(GoodsCategoryEntity.class).eq(GoodsCategoryEntity::getIdnumber,number ));
		return Func.isEmpty(entity )?new GoodsCategoryEntity ():entity;
}





相关文章:

  • 网站推广策略的主要方式/英文网站seo发展前景
  • 北京网站建设资讯/淘宝网官方网站
  • 企业网站方案设计/电商引流推广方法
  • 电子商务网站的目的/自助建站官网
  • 建设通网站/百度入驻绍兴
  • zblogphp和wordpress/每日关键词搜索排行
  • 浅谈如何做好质量保障
  • 【论文简述】FlowFormer:A Transformer Architecture for Optical Flow(ECCV 2022)
  • Android 深入系统完全讲解(21)
  • 【图灵商城】前、后端项目搭建与运行
  • 视频场景切换检测(镜头边界检测、镜头分割)
  • OSCP-Vulnhub靶机记录-Hacker_Kid-v1.0.1
  • CSS 伪元素也可以被用于反爬案例?来学习一下。26
  • 医疗电气设备安规术语理解
  • 从南丁格尔图到医学发展史
  • Delphi 11.2 安装 CnWizards 组件包
  • 基础数字(一)位运算 哈希(数组中元素出现次数)
  • 高精度减法【c++】超详细讲解