最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何交换整型数组的索引与值实现置换逆运算
时间:2026-07-07 09:49:52 编辑:袖梨 来源:一聚教程网
本文详解如何将一个表示置换的整型数组“反转”——即构建其逆置换:原数组中 arr[i] = j 表示索引 i 映射到值 j,目标是构造新数组 inv[j] = i,常用于密码学轮转器(如恩尼格玛仿真)中的编码/解码对称操作。
本文详解如何将一个表示置换的整型数组“反转”——即构建其逆置换:原数组中 `arr[i] = j` 表示索引 i 映射到值 j,目标是构造新数组 `inv[j] = i`,常用于密码学轮转器(如恩尼格玛仿真)中的编码/解码对称操作。
在实现类似恩尼格玛机器的置换逻辑时,常需对编码轮(rotor)的正向映射求逆——例如,若正向模式为 [4, 0, 3, 1, 2](即输入 0→输出 4,输入 1→输出 0,依此类推),则其逆置换应为 [1, 3, 4, 2, 0](即输出 0←来自输入 1,输出 1←来自输入 3,…)。这一操作本质是交换数组的索引与值角色:将原数组视为一个双射函数 f(i) = arr[i],目标是构造 f⁻¹(j) = i。
正确实现的关键在于避免原地修改干扰遍历。常见错误是直接复用同一数组进行赋值(如 R1.Pattern[origPatt[i]] = i),而未提前保存原始状态。由于 origPatt = R1.Pattern 仅复制引用,后续写入 R1.Pattern[...] 会实时覆盖尚未读取的原始值,导致逻辑错乱。
✅ 正确做法是:
- 先创建独立副本(如使用 .clone() 或新建数组);
- 用原始值作为新数组的索引,用原索引作为新数组的值;
- 确保原数组内容在整个循环中保持不变。
以下是安全、清晰的 Java 实现:
int[] original = {4, 0, 3, 1, 2}; // 正向置换:f(0)=4, f(1)=0, f(2)=3, f(3)=1, f(4)=2int[] inverse = new int[original.length];// 构造逆置换:令 inverse[original[i]] = ifor (int i = 0; i < original.length; i++) { inverse[original[i]] = i;}// 输出结果:[1, 3, 4, 2, 0]System.out.println(Arrays.toString(inverse)); // [1, 3, 4, 2, 0]
⚠️ 注意事项:
- 数组必须是有效置换:original 应为 0 到 n−1 的一个排列(无重复、无越界),否则 original[i] 作为索引可能抛出 ArrayIndexOutOfBoundsException;
- 不可原地计算:切勿在 original 上直接赋值,必须使用独立的目标数组;
- 若需就地更新,应先深拷贝:int[] origCopy = R1.Pattern.clone();,再基于 origCopy 构建逆置换并写回 R1.Pattern;
- 此方法时间复杂度 O(n),空间复杂度 O(n),是最优解。
总结:交换索引与值的本质是构建置换的数学逆元。牢记“以值为新索引、以原索引为新值”,并严格分离读写内存区域,即可稳健支持密码学仿真等对确定性映射有严格要求的场景。
相关文章
- 《Disney Lorcana: Wilds Unknown》预购开启 首批《Toy Story》及皮克斯卡牌购买指南 07-29
- 车来了赶车闹钟如何设置 07-29
- 崩坏星穹铁道余晖残卷巨剑守护打法攻略 07-29
- 崩坏星穹铁道砂金角色部分背景介绍 07-29
- 崩坏3雷电芽衣什么时候上线 07-29
- 玩具熊的五夜后宫4代噩梦气球男孩Nightmare Balloon Boy介绍 07-29