Java中如何基于Pair键关联与分数排序生成目标连续字符串
问题解决说明
原实现的核心错误
- 误解了分数的作用:分数仅用于筛选需要剔除的闭合收尾项,也就是全Map中分数最低的Pair(本例中为
(4,1)),这类项不参与后续拼接,和有效Pair的拼接顺序没有关联。原代码直接按分数降序硬拼,一方面会把本该删除的闭合项拼入结果,另一方面按分数排序得到的有效Pair顺序是(1,2)->(3,4)->(2,3),数值无法衔接,根本得不到目标字符串。 - 错误的拼接规则:正确的拼接逻辑是依靠Pair的数值关联——
前一个Pair的右值 = 后一个Pair的左值,靠衔接关系串成连续数字串,不能靠分数排序直接定拼接顺序。
正确实现流程
- 筛选剔除:遍历Map找到分数最低的Entry,后续处理直接跳过这个Pair。
- 构建衔接映射:把剩余的有效Pair存成「左值 -> 右值」的快速查找表,同时记录所有出现过的右值。
- 定位链路起点:遍历有效Pair的左值,找到没有被任何右值指向的那个值,就是目标字符串的起始字符。
- 沿链路拼接:从起点开始,通过映射表每次找到下一个衔接的右值追加到字符串,直到把所有有效Pair串完。
可运行示例代码
import javafx.util.Pair; import java.util.*; public class PairChainBuilder { public static void main(String[] args) { LinkedHashMap<Pair<Integer, Integer>, Double> list = new LinkedHashMap<>(); list.put(new Pair<>(4, 1), 20.12); list.put(new Pair<>(2, 3), 110.58); list.put(new Pair<>(1, 2), 132.61); list.put(new Pair<>(3, 4), 118.54); // 查找分数最低的闭合项 Map.Entry<Pair<Integer, Integer>, Double> minScoreEntry = list.entrySet() .stream() .min(Map.Entry.comparingByValue()) .orElseThrow(); // 构建衔接映射、记录所有右值 Map<Integer, Integer> chainMap = new HashMap<>(); Set<Integer> rightValues = new HashSet<>(); for (Map.Entry<Pair<Integer, Integer>, Double> entry : list.entrySet()) { if (entry.getKey().equals(minScoreEntry.getKey())) { continue; } Pair<Integer, Integer> pair = entry.getKey(); chainMap.put(pair.getLeft(), pair.getRight()); rightValues.add(pair.getRight()); } // 查找链路起点 int start = 0; for (Integer left : chainMap.keySet()) { if (!rightValues.contains(left)) { start = left; break; } } // 拼接最终字符串 StringBuilder result = new StringBuilder(); result.append(start); int current = start; while (chainMap.containsKey(current)) { int next = chainMap.get(current); result.append(next); current = next; } System.out.println(result); // 输出结果1234 } }
备注:代码中使用的
Pair类如果来自其他依赖(比如Apache Commons的org.apache.commons.lang3.tuple.Pair),只要保留getLeft()/getRight()方法定义,逻辑完全通用。
内容的提问来源于stack exchange,提问作者jaydee-187
相关产品推荐
相关产品推荐

