仅对重复长度≥K的序列游程编码:编码器实现求助
实现数字流的TypeA/TypeB编码器
给定数字迭代器(比如[2,3,1,1,1,1,1,5,6])和数值K,需要把数字流编码成对象列表:当连续的同一数字重复K次及以上时,用TypeA对象编码;其余情况用TypeB对象编码。类定义如下:
class TypeA { int num; int count; } class TypeB { int[] nums; }
示例
- 输入
[2,3,1,1,1,1,1,5,6]且K=5时,返回[TypeB([2,3]), TypeA(1,5), TypeB([5,6])] - 输入
[2,3,1,1,1,1,5,6]且K=5时,返回[TypeB([2,3,1,1,1,1,5,6])]
解决思路
核心是跟踪当前连续数字的状态,同时维护一个临时列表缓存不够K次的数字。因为必须等当前连续数字的计数确定是否达标后,才能决定是输出缓存的TypeB,还是输出当前组的TypeA并清空缓存。具体步骤:
- 初始化当前数字、连续计数,以及一个临时列表用于缓存待转为
TypeB的数字。 - 遍历迭代器:
- 遇到相同数字就累加计数。
- 遇到不同数字时,先处理当前连续组:
- 如果计数≥K:把临时列表转为
TypeB加入结果(非空时),再把当前组转为TypeA加入结果,清空临时列表。 - 如果计数<K:把当前数字重复对应次数加入临时列表。
- 如果计数≥K:把临时列表转为
- 遍历结束后,处理最后一组连续数字,再把剩余的临时列表转为
TypeB(非空时)。
代码实现(Java)
import java.util.ArrayList; import java.util.Iterator; import java.util.List; class TypeA { int num; int count; public TypeA(int num, int count) { this.num = num; this.count = count; } @Override public String toString() { return "TypeA(" + num + "," + count + ")"; } } class TypeB { int[] nums; public TypeB(int[] nums) { this.nums = nums; } @Override public String toString() { StringBuilder sb = new StringBuilder("TypeB(["); for (int i = 0; i < nums.length; i++) { if (i > 0) sb.append(","); sb.append(nums[i]); } sb.append("])"); return sb.toString(); } } public class Encoder { public static List<Object> encode(Iterator<Integer> iterator, int K) { List<Object> result = new ArrayList<>(); if (!iterator.hasNext()) { return result; } int currNum = iterator.next(); int currCount = 1; List<Integer> tempBList = new ArrayList<>(); while (iterator.hasNext()) { int num = iterator.next(); if (num == currNum) { currCount++; } else { processCurrentGroup(currNum, currCount, K, tempBList, result); currNum = num; currCount = 1; } } // 处理最后一组连续数字 processCurrentGroup(currNum, currCount, K, tempBList, result); // 把剩余的临时列表转为TypeB if (!tempBList.isEmpty()) { result.add(new TypeB(tempBList.stream().mapToInt(Integer::intValue).toArray())); } return result; } private static void processCurrentGroup(int currNum, int currCount, int K, List<Integer> tempBList, List<Object> result) { if (currCount >= K) { // 当前组达标,先输出缓存的TypeB if (!tempBList.isEmpty()) { result.add(new TypeB(tempBList.stream().mapToInt(Integer::intValue).toArray())); tempBList.clear(); } // 输出当前组的TypeA result.add(new TypeA(currNum, currCount)); } else { // 当前组不达标,加入缓存 for (int i = 0; i < currCount; i++) { tempBList.add(currNum); } } } public static void main(String[] args) { // 测试示例1 List<Integer> input1 = List.of(2,3,1,1,1,1,1,5,6); List<Object> output1 = encode(input1.iterator(), 5); System.out.println(output1); // 输出:[TypeB([2,3]), TypeA(1,5), TypeB([5,6])] // 测试示例2 List<Integer> input2 = List.of(2,3,1,1,1,1,5,6); List<Object> output2 = encode(input2.iterator(), 5); System.out.println(output2); // 输出:[TypeB([2,3,1,1,1,1,5,6])] } }
关键说明
- 用
tempBList缓存所有未达标的连续数字,避免提前输出TypeB导致后续出现达标组时无法拆分。 - 处理迭代器的空输入情况,确保鲁棒性。
- 最后必须处理剩余的临时列表,避免遗漏未达标的数字。
内容的提问来源于stack exchange,提问作者jmtt
相关产品推荐
相关产品推荐

