From 52bdf53efb66c4b6de914b56771b93c023a4a36b Mon Sep 17 00:00:00 2001 From: cmm <1580166554@qq.com> Date: Sun, 4 Aug 2024 00:17:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/text/finder/MultiStrFinder.java | 58 +++++++++---------- .../text/replacer/HighMultiReplacerV2.java | 28 ++++----- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/MultiStrFinder.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/MultiStrFinder.java index 283327c67..9f2155881 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/MultiStrFinder.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/finder/MultiStrFinder.java @@ -9,18 +9,16 @@ import java.util.*; */ public class MultiStrFinder { - /** 字符索引 **/ + // 字符索引 protected final Map charIndex = new HashMap<>(); - /** 全部字符数量 **/ + // 全部字符数量 protected final int allCharSize; - /** 根节点 **/ + // 根节点 protected final Node root; - /** - * 全部节点数量 - */ + // 全部节点数量 int nodeSize; /** @@ -28,13 +26,13 @@ public class MultiStrFinder { * @param source */ public MultiStrFinder(Collection source){ - /** 待匹配的字符串 **/ - final Set stringSst = new HashSet<>(); + // 待匹配的字符串 + final Set stringSet = new HashSet<>(); - /** 所有字符 **/ + // 所有字符 final Set charSet = new HashSet<>(); for (String string : source) { - stringSst.add(string); + stringSet.add(string); char[] charArray = string.toCharArray(); for (char c : charArray) { charSet.add(c); @@ -49,7 +47,7 @@ public class MultiStrFinder { root = Node.createRoot(allCharSize); - buildPrefixTree(stringSst); + buildPrefixTree(stringSet); buildFail(); } @@ -58,7 +56,7 @@ public class MultiStrFinder { * @param stringSst 待匹配的字符串 */ protected void buildPrefixTree(Collection stringSst){ - /** 节点编号 根节点已经是0了 所以从 1开始编号 **/ + // 节点编号 根节点已经是0了 所以从 1开始编号 int nodeIndex = 1; for (String string : stringSst) { Node node = root; @@ -92,15 +90,13 @@ public class MultiStrFinder { nodeQueue.addLast(nextNode); } - /* 进行广度优先遍历 **/ + // 进行广度优先遍历 while (!nodeQueue.isEmpty()){ Node parent = nodeQueue.removeFirst(); - /** - * 因为 使用了 charIndex 进行字符到下标的映射 i 可以直接认为就是对应字符 char - */ + // 因为 使用了 charIndex 进行字符到下标的映射 i 可以直接认为就是对应字符 char for (int i = 0; i < parent.directRouter.length; i++) { Node child = parent.directRouter[i]; - /* child 为 null 表示没有子节点 **/ + // child 为 null 表示没有子节点 if(child == null){ parent.directRouter[i] = parent.fail.directRouter[i]; continue; @@ -118,7 +114,7 @@ public class MultiStrFinder { * @return */ public Map> findMatch(String text){ - /* 节点经过次数 放在方法内部声明变量 希望可以一个构建对象 进行多次匹配 */ + // 节点经过次数 放在方法内部声明变量 希望可以一个构建对象 进行多次匹配 HashMap> resultMap = new HashMap<>(); char[] chars = text.toCharArray(); @@ -126,14 +122,14 @@ public class MultiStrFinder { for (int i = 0; i < chars.length; i++) { char c = chars[i]; Integer index = charIndex.get(c); - /* 找不到字符索引 认为一定不在匹配字符中存在 直接从根节点开始重新计算 */ + // 找不到字符索引 认为一定不在匹配字符中存在 直接从根节点开始重新计算 if(index == null){ currentNode = root; continue; } - /* 进入下一跳 可能是正常下一跳 也可能是fail加上后的 下一跳 */ + // 进入下一跳 可能是正常下一跳 也可能是fail加上后的 下一跳 currentNode = currentNode.directRouter[index]; - /* 判断是否尾部节点 是尾节点 说明已经匹配到了完整的字符串 将匹配结果写入返回对象 */ + // 判断是否尾部节点 是尾节点 说明已经匹配到了完整的字符串 将匹配结果写入返回对象 if(currentNode.isEnd){ resultMap.computeIfAbsent(currentNode.tagetString, k -> new ArrayList<>()) .add(i - currentNode.tagetString.length() + 1); @@ -167,15 +163,13 @@ public class MultiStrFinder { * AC 自动机节点 */ protected static class Node { - /** 是否是字符串 尾节点 **/ + // 是否是字符串 尾节点 public boolean isEnd = false; - /** 如果当前节点是尾节点 那么表示 匹配到的字符串 其他情况下 null **/ + // 如果当前节点是尾节点 那么表示 匹配到的字符串 其他情况下 null public String tagetString; - /** - * 失效节点 - */ + //失效节点 public Node fail; /** @@ -186,13 +180,13 @@ public class MultiStrFinder { */ public Node[] directRouter; - /** 节点编号 root 为 0 **/ + // 节点编号 root 为 0 public int nodeIndex; - /** 值 **/ + // 值 public char value; - /** fail指针来源 **/ + // fail指针来源 public List failPre = new ArrayList<>(); public Node(){} @@ -229,8 +223,8 @@ public class MultiStrFinder { /** * 获取下一跳 - * @param c - * @param charIndex + * @param c 字符 + * @param charIndex 字符索引 * @return */ public Node getNext(char c,Map charIndex){ @@ -243,7 +237,7 @@ public class MultiStrFinder { /** * 构建根节点 - * @param allCharSize + * @param allCharSize 全部字符数量 * @return */ public static Node createRoot(int allCharSize){ diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/replacer/HighMultiReplacerV2.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/replacer/HighMultiReplacerV2.java index 412f230f9..3f79eae24 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/replacer/HighMultiReplacerV2.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/replacer/HighMultiReplacerV2.java @@ -57,52 +57,52 @@ public class HighMultiReplacerV2 extends StrReplacer { public void replace(final CharSequence text, final StringBuilder stringBuilder){ Node currentNode = root; - /* 临时字符串存储空间 **/ + // 临时字符串存储空间 StringBuilder temp = new StringBuilder(); for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); Integer index = charIndex.get(ch); - /* 下一个字符在候选转换字符串中都不存在 ch字符一定不会被替换 */ + // 下一个字符在候选转换字符串中都不存在 ch字符一定不会被替换 if(index < 0){ - /* 临时缓存空间中的数据写入到输出的 StringBuilder */ + // 临时缓存空间中的数据写入到输出的 StringBuilder if(temp.length() > 0){ stringBuilder.append(temp); - /* 数据写入后清空临时空间 */ + // 数据写入后清空临时空间 temp.delete(0, temp.length()); } - /* 将一个一定不会替换的字符 ch 写入输出 */ + // 将一个一定不会替换的字符 ch 写入输出 stringBuilder.append(ch); - /* 匹配失败 将当前节点重新指向根节点 */ + // 匹配失败 将当前节点重新指向根节点 currentNode = root; continue; } - /* 这个逻辑分支表示 已经匹配到了下一跳 */ + // 这个逻辑分支表示 已经匹配到了下一跳 currentNode = currentNode.directRouter[index]; - /* 当前是root节点表示匹配中断 清理临时空间 写入到输出 */ + // 当前是root节点表示匹配中断 清理临时空间 写入到输出 if(currentNode.nodeIndex == 0){ if(temp.length() > 0){ stringBuilder.append(temp); - /* 数据写入后清空临时空间 */ + // 数据写入后清空临时空间 temp.delete(0, temp.length()); - /* 当前情况表示该字符存在在候选转换字符中 但是前一个字符到这里是不存在路径 */ + // 当前情况表示该字符存在在候选转换字符中 但是前一个字符到这里是不存在路径 stringBuilder.append(ch); continue; } } - /* 表示匹配到 现在进行字符串替换工作 */ + // 表示匹配到 现在进行字符串替换工作 if(currentNode.isEnd){ int length = currentNode.tagetString.length(); - /* 先清理匹配到的字符 最后一个字符未加入临时空间 */ + // 先清理匹配到的字符 最后一个字符未加入临时空间 temp.delete(temp.length() - length + 1,length - 1); if(temp.length() > 0){ stringBuilder.append(temp); } - /* 写入被替换的字符串 */ + // 写入被替换的字符串 stringBuilder.append(replaceMap.get(currentNode.tagetString)); - /* 因为字符串被替换过了 所以当前节点重新指向 root */ + // 因为字符串被替换过了 所以当前节点重新指向 root currentNode = root; continue; }