You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

十五数码游戏中Config实例参数被意外修改问题求助

解决十五数码游戏中Config实例被意外修改的问题

这绝对是浅拷贝搞的鬼!你现在的问题本质是:复制Config实例的时候,只是把数组的引用复制给了新实例,并没有创建一个全新的数组对象。所以原来的实例A和新生成的实例B,它们的board数组指向的是内存里同一个区域——改B的数组,自然A的数组也会跟着变,因为根本就是同一个东西!

问题根源确认

先看看你复制Config的代码是不是类似这样(假设是Java语言,毕竟你提到了int数组和类实例):

// 错误的构造函数——浅拷贝数组引用
public class Config {
    private int[] board;

    public Config(int[] board) {
        this.board = board; // 直接赋值引用,两个实例共享同一个数组
    }

    // 你的移动方法
    public Config moveUp(Config a) {
        Config b = new Config(a.board); // 这里还是传引用
        // 找到0的位置并交换
        int zeroPos = findZero(b.board);
        if (zeroPos >= 4) {
            swap(b.board, zeroPos, zeroPos - 4);
        }
        return b;
    }
}

这种写法下,A和B的board是同一个数组,不管你改哪一个,另一个都会同步变化。

解决方案:实现数组的深拷贝

因为int是基本数据类型,我们只需要创建一个新的数组,把原数组的元素逐个复制进去就行,这样每个Config实例都拥有独立的数组。

方法1:修改Config的构造函数

让构造函数接收数组时,自动创建数组副本:

import java.util.Arrays;

public class Config {
    private int[] board;

    public Config(int[] board) {
        // 使用Arrays.copyOf创建新数组,复制所有元素
        this.board = Arrays.copyOf(board, board.length);
    }

    // 或者用数组的clone方法,对于基本类型数组,clone是值拷贝
    // this.board = board.clone();
}

这样不管你用哪个移动方法创建新实例,新的Config都会拥有自己独立的数组,修改它不会影响原实例。

方法2:在移动方法中显式复制数组

如果不想修改构造函数,也可以在移动方法里先复制数组,再创建新实例:

public Config moveUp(Config a) {
    // 先复制原实例的数组
    int[] newBoard = Arrays.copyOf(a.board, a.board.length);
    Config b = new Config(newBoard);
    // 后续操作都针对newBoard,不会影响a的数组
    int zeroPos = findZero(newBoard);
    if (zeroPos >= 4) {
        swap(newBoard, zeroPos, zeroPos - 4);
    }
    return b;
}

验证效果

修改后,你再调用移动方法得到B,然后打印A的棋盘状态,就会发现A还是原来的样子,B是移动后的状态,两者互不影响了。

内容的提问来源于stack exchange,提问作者Rodrigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:01:16