linkedList实现高亮逻辑

简介: linkedList实现高亮逻辑

渴望像神话中巨型的黄色罗马蜡烛那样燃烧。——杰克·凯鲁亚克《在路上》

这里是基于hutooldfa查找法得到的结果集进行封装,不一定非要依赖hutool,可以自定义FoundWord对象,里面就只用到了一个起始下标,以及对应需要高亮的词汇

public static String highlight(String text, List<FoundWord> fondWords, UnaryOperator<String> highlightOperator) {
    if (Opp.ofColl(fondWords).isEmpty() || Opp.ofStr(text).isEmpty()) {
        return text;
    }
    fondWords = Steam.of(fondWords)
            .sorted(Comparator.comparing(FoundWord::getIndex)
                    .thenComparingInt(w -> w.getWord().length()))
            .toList();
    LinkedList<FoundWord> linkedList = new LinkedList<>();
    // 记录历史下标(当前拼接到整体string的哪个位置了)
    int lastIdx = 0;
    // 进行遍历所有结果(理论上已按照 startIndex和fondWord.length排序)
    for (int i = 0; i < fondWords.size(); i++) {
        FoundWord fondWord = fondWords.get(i);
        String word = null;
        // 如果本次匹配发现历史下标已经超过了当前匹配值,说明这次词语和上次词语下标重复或者是上次的一部分
        if (i > 0 && lastIdx > fondWord.getIndex()) {
            // 移除拼接的额外部分
            FoundWord last = Objects.requireNonNull(linkedList.pollLast());
            // 判断上次和这次的长度,如果上次长度大于这次长度,说明这次词语是上次的一部分
            lastIdx -= last.getWord().length();
            // 获取要从哪里开始保留
            int index = fondWord.getWord().indexOf(last.getWord().charAt(last.getWord().length() - 1));
            // 这里没有判断是否找到是因为只要进入当前的if语句那么必定有重复串可以找到
            String suffix = fondWord.getWord().substring(index+1);
            word = last.getWord() + suffix;
        } else {
            // 否则根据历史下标到当前词汇下标进行查找额外部分
            String partOne = text.substring(lastIdx, fondWord.getIndex());
            // 并且将历史下标往前推进
            lastIdx += partOne.length();
            // 将额外部分拼接到链表中
            linkedList.add(new FoundWord(partOne, lastIdx));
        }
        // 获取本次需要高亮的词汇
        word = Opp.ofStr(word).orElseGet(fondWord::getWord);
        // 历史下标往前推进
        lastIdx += word.length();
        // 执行高亮操作
        linkedList.add(new FoundWord(word, highlightOperator.apply(word), lastIdx));
    }
    // 别忘了加上最后一截
    linkedList.add(new FoundWord(text.substring(lastIdx), text.substring(lastIdx), lastIdx));
    return Steam.of(linkedList).map(FoundWord::getWordAfterHighlight).join();
}


使用:

WordTree tree = new WordTree();
tree.addWord("大");
tree.addWord("大土豆");
tree.addWord("土豆");
tree.addWord("刚出锅");
tree.addWord("出锅");
String text = "我有一颗大土豆,刚出锅的";
List<FoundWord> foundWords = tree.matchAllWords(text, -1, true, true);
String result = CommonUtils.highlight(text, foundWords, s -> "<span style='color:red'>" + s + "</span>");
System.out.println(result);

效果:

这里重载了一个needSort,如果是自定义的FoundWord,需要指定为true,手动进行排序

相关文章
|
存储 Java API
阿里云OSS使用购买流程
本文介绍了阿里云对象存储OSS的基本使用,包括准备工作、购买开通阿里云账号并进行实名认证,以及通过Web控制台、命令行工具ossutil和SDK进行文件操作。此外,还提到了RESTful API和图形化工具OSSBrowser的使用,并给出了Java SDK下载对象的示例代码。文章内容包括了OSS的基本概念,如存储空间Bucket和对象Object,以及不同类型的存储类型。
|
前端开发
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十六题-display-flex
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十六题-display-flex
87 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十六题-display-flex
|
弹性计算 Linux 数据安全/隐私保护
如何购买阿里云服务器ECS更便宜实惠?
为了让新手了解去服务器,本期我们主要介绍如何购买阿里云ECS服务器,希望能通过我的经验,能帮助到大家!
|
传感器 算法 自动驾驶
导航定位向高精定位的演进与实践
本文较系统的介绍了手机、车机导航定位中使用的关键技术,以及高德地图在这些关键技术中的进展。最后,讨论了在传统导航向自动驾驶的演进过程中,定位技术的演进路径。
导航定位向高精定位的演进与实践
|
13天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
12天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
393 135