C#中G-Code字符串数组重复片段分组压缩需求咨询
G-Code ArrayList重复连续片段压缩实现
需求
处理从文件导入的G-Code字符串ArrayList,将连续重复的指定片段替换为GroupX N times格式的条目(X为分组编号,N为重复次数),非重复的G-Code语句直接保留。
输入示例
ArrayList<String> arrn = new ArrayList<>() {{ add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G1 X40,000 Y0,000 F3570"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); }};
待匹配的重复片段
- Group1 片段(长度4行)
List<String> group1 = Arrays.asList( "G3 X10,000 Y-10,000 Z-10,000", "G3 X10,000 Y10,000 Z-10,000", "G2 X10,000 Y10,000 Z-10,000", "G2 X10,000 Y-10,000 Z-10,000" );
- Group2 片段(长度4行)
List<String> group2 = Arrays.asList( "G2 X15,000 Y15,000 Z-15,000", "G2 X15,000 Y-15,000 Z-15,000", "G3 X15,000 Y-15,000 Z-15,000", "G3 X15,000 Y15,000 Z-15,000" );
期望输出
ArrayList<String> compressedArr = new ArrayList<>() {{ add("Group1 2 times"); add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G1 X40,000 Y0,000 F3570"); add("Group2 3 times"); }};
实现方案(Java)
核心逻辑
- 定义所有待匹配的分组片段,绑定对应的Group名称
- 遍历输入数组时,从当前位置尝试匹配所有分组片段
- 若匹配成功,统计连续重复的次数,跳过对应行数,添加压缩条目到结果
- 若未匹配到任何片段,直接将当前行加入结果
代码实现
import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class GCodeCompressor { public static void main(String[] args) { // 输入的G-Code数组 List<String> inputGCode = new ArrayList<>() {{ add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y10,000 Z-10,000"); add("G2 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y-10,000 Z-10,000"); add("G3 X10,000 Y10,000 Z-10,000"); add("G1 X40,000 Y0,000 F3570"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y15,000 Z-15,000"); add("G2 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y-15,000 Z-15,000"); add("G3 X15,000 Y15,000 Z-15,000"); }}; // 定义待匹配的分组片段及对应的名称 List<Group> groups = Arrays.asList( new Group("Group1", Arrays.asList( "G3 X10,000 Y-10,000 Z-10,000", "G3 X10,000 Y10,000 Z-10,000", "G2 X10,000 Y10,000 Z-10,000", "G2 X10,000 Y-10,000 Z-10,000" )), new Group("Group2", Arrays.asList( "G2 X15,000 Y15,000 Z-15,000", "G2 X15,000 Y-15,000 Z-15,000", "G3 X15,000 Y-15,000 Z-15,000", "G3 X15,000 Y15,000 Z-15,000" )) ); List<String> compressedResult = new ArrayList<>(); int i = 0; int inputSize = inputGCode.size(); while (i < inputSize) { boolean matched = false; // 尝试匹配所有分组 for (Group group : groups) { int groupLength = group.getFragment().size(); // 剩余行数不足,跳过 if (i + groupLength > inputSize) continue; // 检查当前位置是否匹配分组片段 boolean isMatch = true; for (int j = 0; j < groupLength; j++) { if (!inputGCode.get(i + j).equals(group.getFragment().get(j))) { isMatch = false; break; } } if (isMatch) { // 统计连续重复次数 int repeatCount = 0; while (i + groupLength <= inputSize) { boolean currentMatch = true; for (int j = 0; j < groupLength; j++) { if (!inputGCode.get(i + j).equals(group.getFragment().get(j))) { currentMatch = false; break; } } if (!currentMatch) break; repeatCount++; i += groupLength; } // 添加压缩条目 compressedResult.add(group.getName() + " " + repeatCount + " times"); matched = true; break; } } // 未匹配到任何分组,直接添加当前行 if (!matched) { compressedResult.add(inputGCode.get(i)); i++; } } // 打印结果验证 for (String line : compressedResult) { System.out.println("\"" + line + "\","); } } // 辅助类:存储分组名称和对应的片段 static class Group { private final String name; private final List<String> fragment; public Group(String name, List<String> fragment) { this.name = name; this.fragment = fragment; } public String getName() { return name; } public List<String> getFragment() { return fragment; } } }
代码说明
- 用
Group类封装每个待匹配片段的名称和内容,便于扩展更多分组 - 遍历输入时优先匹配分组,匹配成功后统计连续重复的次数,一次性跳过对应行数
- 未匹配的行直接保留,完全符合需求中的输出格式
内容的提问来源于stack exchange,提问作者Vazili_Zaitzef
相关产品推荐
相关产品推荐

