mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
修改代码注释形式
This commit is contained in:
parent
86f6b24460
commit
52bdf53efb
@ -9,18 +9,16 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class MultiStrFinder {
|
public class MultiStrFinder {
|
||||||
|
|
||||||
/** 字符索引 **/
|
// 字符索引
|
||||||
protected final Map<Character,Integer> charIndex = new HashMap<>();
|
protected final Map<Character,Integer> charIndex = new HashMap<>();
|
||||||
|
|
||||||
/** 全部字符数量 **/
|
// 全部字符数量
|
||||||
protected final int allCharSize;
|
protected final int allCharSize;
|
||||||
|
|
||||||
/** 根节点 **/
|
// 根节点
|
||||||
protected final Node root;
|
protected final Node root;
|
||||||
|
|
||||||
/**
|
// 全部节点数量
|
||||||
* 全部节点数量
|
|
||||||
*/
|
|
||||||
int nodeSize;
|
int nodeSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,13 +26,13 @@ public class MultiStrFinder {
|
|||||||
* @param source
|
* @param source
|
||||||
*/
|
*/
|
||||||
public MultiStrFinder(Collection<String> source){
|
public MultiStrFinder(Collection<String> source){
|
||||||
/** 待匹配的字符串 **/
|
// 待匹配的字符串
|
||||||
final Set<String> stringSst = new HashSet<>();
|
final Set<String> stringSet = new HashSet<>();
|
||||||
|
|
||||||
/** 所有字符 **/
|
// 所有字符
|
||||||
final Set<Character> charSet = new HashSet<>();
|
final Set<Character> charSet = new HashSet<>();
|
||||||
for (String string : source) {
|
for (String string : source) {
|
||||||
stringSst.add(string);
|
stringSet.add(string);
|
||||||
char[] charArray = string.toCharArray();
|
char[] charArray = string.toCharArray();
|
||||||
for (char c : charArray) {
|
for (char c : charArray) {
|
||||||
charSet.add(c);
|
charSet.add(c);
|
||||||
@ -49,7 +47,7 @@ public class MultiStrFinder {
|
|||||||
|
|
||||||
root = Node.createRoot(allCharSize);
|
root = Node.createRoot(allCharSize);
|
||||||
|
|
||||||
buildPrefixTree(stringSst);
|
buildPrefixTree(stringSet);
|
||||||
buildFail();
|
buildFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +56,7 @@ public class MultiStrFinder {
|
|||||||
* @param stringSst 待匹配的字符串
|
* @param stringSst 待匹配的字符串
|
||||||
*/
|
*/
|
||||||
protected void buildPrefixTree(Collection<String> stringSst){
|
protected void buildPrefixTree(Collection<String> stringSst){
|
||||||
/** 节点编号 根节点已经是0了 所以从 1开始编号 **/
|
// 节点编号 根节点已经是0了 所以从 1开始编号
|
||||||
int nodeIndex = 1;
|
int nodeIndex = 1;
|
||||||
for (String string : stringSst) {
|
for (String string : stringSst) {
|
||||||
Node node = root;
|
Node node = root;
|
||||||
@ -92,15 +90,13 @@ public class MultiStrFinder {
|
|||||||
nodeQueue.addLast(nextNode);
|
nodeQueue.addLast(nextNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 进行广度优先遍历 **/
|
// 进行广度优先遍历
|
||||||
while (!nodeQueue.isEmpty()){
|
while (!nodeQueue.isEmpty()){
|
||||||
Node parent = nodeQueue.removeFirst();
|
Node parent = nodeQueue.removeFirst();
|
||||||
/**
|
// 因为 使用了 charIndex 进行字符到下标的映射 i 可以直接认为就是对应字符 char
|
||||||
* 因为 使用了 charIndex 进行字符到下标的映射 i 可以直接认为就是对应字符 char
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < parent.directRouter.length; i++) {
|
for (int i = 0; i < parent.directRouter.length; i++) {
|
||||||
Node child = parent.directRouter[i];
|
Node child = parent.directRouter[i];
|
||||||
/* child 为 null 表示没有子节点 **/
|
// child 为 null 表示没有子节点
|
||||||
if(child == null){
|
if(child == null){
|
||||||
parent.directRouter[i] = parent.fail.directRouter[i];
|
parent.directRouter[i] = parent.fail.directRouter[i];
|
||||||
continue;
|
continue;
|
||||||
@ -118,7 +114,7 @@ public class MultiStrFinder {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Map<String,List<Integer>> findMatch(String text){
|
public Map<String,List<Integer>> findMatch(String text){
|
||||||
/* 节点经过次数 放在方法内部声明变量 希望可以一个构建对象 进行多次匹配 */
|
// 节点经过次数 放在方法内部声明变量 希望可以一个构建对象 进行多次匹配
|
||||||
HashMap<String, List<Integer>> resultMap = new HashMap<>();
|
HashMap<String, List<Integer>> resultMap = new HashMap<>();
|
||||||
|
|
||||||
char[] chars = text.toCharArray();
|
char[] chars = text.toCharArray();
|
||||||
@ -126,14 +122,14 @@ public class MultiStrFinder {
|
|||||||
for (int i = 0; i < chars.length; i++) {
|
for (int i = 0; i < chars.length; i++) {
|
||||||
char c = chars[i];
|
char c = chars[i];
|
||||||
Integer index = charIndex.get(c);
|
Integer index = charIndex.get(c);
|
||||||
/* 找不到字符索引 认为一定不在匹配字符中存在 直接从根节点开始重新计算 */
|
// 找不到字符索引 认为一定不在匹配字符中存在 直接从根节点开始重新计算
|
||||||
if(index == null){
|
if(index == null){
|
||||||
currentNode = root;
|
currentNode = root;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* 进入下一跳 可能是正常下一跳 也可能是fail加上后的 下一跳 */
|
// 进入下一跳 可能是正常下一跳 也可能是fail加上后的 下一跳
|
||||||
currentNode = currentNode.directRouter[index];
|
currentNode = currentNode.directRouter[index];
|
||||||
/* 判断是否尾部节点 是尾节点 说明已经匹配到了完整的字符串 将匹配结果写入返回对象 */
|
// 判断是否尾部节点 是尾节点 说明已经匹配到了完整的字符串 将匹配结果写入返回对象
|
||||||
if(currentNode.isEnd){
|
if(currentNode.isEnd){
|
||||||
resultMap.computeIfAbsent(currentNode.tagetString, k -> new ArrayList<>())
|
resultMap.computeIfAbsent(currentNode.tagetString, k -> new ArrayList<>())
|
||||||
.add(i - currentNode.tagetString.length() + 1);
|
.add(i - currentNode.tagetString.length() + 1);
|
||||||
@ -167,15 +163,13 @@ public class MultiStrFinder {
|
|||||||
* AC 自动机节点
|
* AC 自动机节点
|
||||||
*/
|
*/
|
||||||
protected static class Node {
|
protected static class Node {
|
||||||
/** 是否是字符串 尾节点 **/
|
// 是否是字符串 尾节点
|
||||||
public boolean isEnd = false;
|
public boolean isEnd = false;
|
||||||
|
|
||||||
/** 如果当前节点是尾节点 那么表示 匹配到的字符串 其他情况下 null **/
|
// 如果当前节点是尾节点 那么表示 匹配到的字符串 其他情况下 null
|
||||||
public String tagetString;
|
public String tagetString;
|
||||||
|
|
||||||
/**
|
//失效节点
|
||||||
* 失效节点
|
|
||||||
*/
|
|
||||||
public Node fail;
|
public Node fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,13 +180,13 @@ public class MultiStrFinder {
|
|||||||
*/
|
*/
|
||||||
public Node[] directRouter;
|
public Node[] directRouter;
|
||||||
|
|
||||||
/** 节点编号 root 为 0 **/
|
// 节点编号 root 为 0
|
||||||
public int nodeIndex;
|
public int nodeIndex;
|
||||||
|
|
||||||
/** 值 **/
|
// 值
|
||||||
public char value;
|
public char value;
|
||||||
|
|
||||||
/** fail指针来源 **/
|
// fail指针来源
|
||||||
public List<Node> failPre = new ArrayList<>();
|
public List<Node> failPre = new ArrayList<>();
|
||||||
|
|
||||||
public Node(){}
|
public Node(){}
|
||||||
@ -229,8 +223,8 @@ public class MultiStrFinder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一跳
|
* 获取下一跳
|
||||||
* @param c
|
* @param c 字符
|
||||||
* @param charIndex
|
* @param charIndex 字符索引
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Node getNext(char c,Map<Character,Integer> charIndex){
|
public Node getNext(char c,Map<Character,Integer> charIndex){
|
||||||
@ -243,7 +237,7 @@ public class MultiStrFinder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建根节点
|
* 构建根节点
|
||||||
* @param allCharSize
|
* @param allCharSize 全部字符数量
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Node createRoot(int allCharSize){
|
public static Node createRoot(int allCharSize){
|
||||||
|
@ -57,52 +57,52 @@ public class HighMultiReplacerV2 extends StrReplacer {
|
|||||||
|
|
||||||
public void replace(final CharSequence text, final StringBuilder stringBuilder){
|
public void replace(final CharSequence text, final StringBuilder stringBuilder){
|
||||||
Node currentNode = root;
|
Node currentNode = root;
|
||||||
/* 临时字符串存储空间 **/
|
// 临时字符串存储空间
|
||||||
StringBuilder temp = new StringBuilder();
|
StringBuilder temp = new StringBuilder();
|
||||||
for (int i = 0; i < text.length(); i++) {
|
for (int i = 0; i < text.length(); i++) {
|
||||||
char ch = text.charAt(i);
|
char ch = text.charAt(i);
|
||||||
Integer index = charIndex.get(ch);
|
Integer index = charIndex.get(ch);
|
||||||
/* 下一个字符在候选转换字符串中都不存在 ch字符一定不会被替换 */
|
// 下一个字符在候选转换字符串中都不存在 ch字符一定不会被替换
|
||||||
if(index < 0){
|
if(index < 0){
|
||||||
/* 临时缓存空间中的数据写入到输出的 StringBuilder */
|
// 临时缓存空间中的数据写入到输出的 StringBuilder
|
||||||
if(temp.length() > 0){
|
if(temp.length() > 0){
|
||||||
stringBuilder.append(temp);
|
stringBuilder.append(temp);
|
||||||
/* 数据写入后清空临时空间 */
|
// 数据写入后清空临时空间
|
||||||
temp.delete(0, temp.length());
|
temp.delete(0, temp.length());
|
||||||
}
|
}
|
||||||
/* 将一个一定不会替换的字符 ch 写入输出 */
|
// 将一个一定不会替换的字符 ch 写入输出
|
||||||
stringBuilder.append(ch);
|
stringBuilder.append(ch);
|
||||||
/* 匹配失败 将当前节点重新指向根节点 */
|
// 匹配失败 将当前节点重新指向根节点
|
||||||
currentNode = root;
|
currentNode = root;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 这个逻辑分支表示 已经匹配到了下一跳 */
|
// 这个逻辑分支表示 已经匹配到了下一跳
|
||||||
currentNode = currentNode.directRouter[index];
|
currentNode = currentNode.directRouter[index];
|
||||||
|
|
||||||
/* 当前是root节点表示匹配中断 清理临时空间 写入到输出 */
|
// 当前是root节点表示匹配中断 清理临时空间 写入到输出
|
||||||
if(currentNode.nodeIndex == 0){
|
if(currentNode.nodeIndex == 0){
|
||||||
if(temp.length() > 0){
|
if(temp.length() > 0){
|
||||||
stringBuilder.append(temp);
|
stringBuilder.append(temp);
|
||||||
/* 数据写入后清空临时空间 */
|
// 数据写入后清空临时空间
|
||||||
temp.delete(0, temp.length());
|
temp.delete(0, temp.length());
|
||||||
/* 当前情况表示该字符存在在候选转换字符中 但是前一个字符到这里是不存在路径 */
|
// 当前情况表示该字符存在在候选转换字符中 但是前一个字符到这里是不存在路径
|
||||||
stringBuilder.append(ch);
|
stringBuilder.append(ch);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表示匹配到 现在进行字符串替换工作 */
|
// 表示匹配到 现在进行字符串替换工作
|
||||||
if(currentNode.isEnd){
|
if(currentNode.isEnd){
|
||||||
int length = currentNode.tagetString.length();
|
int length = currentNode.tagetString.length();
|
||||||
/* 先清理匹配到的字符 最后一个字符未加入临时空间 */
|
// 先清理匹配到的字符 最后一个字符未加入临时空间
|
||||||
temp.delete(temp.length() - length + 1,length - 1);
|
temp.delete(temp.length() - length + 1,length - 1);
|
||||||
if(temp.length() > 0){
|
if(temp.length() > 0){
|
||||||
stringBuilder.append(temp);
|
stringBuilder.append(temp);
|
||||||
}
|
}
|
||||||
/* 写入被替换的字符串 */
|
// 写入被替换的字符串
|
||||||
stringBuilder.append(replaceMap.get(currentNode.tagetString));
|
stringBuilder.append(replaceMap.get(currentNode.tagetString));
|
||||||
/* 因为字符串被替换过了 所以当前节点重新指向 root */
|
// 因为字符串被替换过了 所以当前节点重新指向 root
|
||||||
currentNode = root;
|
currentNode = root;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user