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

为何未主动修改时firstState、state数组值仍变化?求解决方案

问题分析与解决方案

问题根源

C#中数组是引用类型,你执行的int[,] state = firstState;和int[,] current = state;并没有创建新的数组实例,只是让firstState、state、current三个变量指向内存中同一个二维数组对象。所以不管通过哪个变量修改数组元素,本质上都是修改同一个底层数组,自然会导致所有变量对应的数组内容同步变化。

修复步骤

要实现独立修改,必须为每个变量创建数组的副本,而不是直接复制引用。对于二维数组,需要手动遍历元素完成深拷贝:

  1. 编写一个克隆二维数组的工具方法:
static int[,] Clone2DArray(int[,] source)
{
    int rowCount = source.GetLength(0);
    int colCount = source.GetLength(1);
    int[,] clonedArray = new int[rowCount, colCount];
    
    for (int i = 0; i < rowCount; i++)
    {
        for (int j = 0; j < colCount; j++)
        {
            clonedArray[i, j] = source[i, j];
        }
    }
    return clonedArray;
}
  1. 修改变量赋值逻辑,使用克隆方法创建独立数组:
int[,] state = Clone2DArray(firstState);
int[,] current = Clone2DArray(state);
  1. 补充:你代码中向ArrayList添加state时,同样会添加引用,后续修改state会导致values中所有元素同步变化。所以添加时也需要克隆:
// 交换操作完成后,克隆数组再添加到集合
int[,] newStateCopy = Clone2DArray(state);
values.Add(newStateCopy);

完整修复后的代码示例

internal class Program
{
    static void Main(string[] args)
    {
        int[,] firstState = new int[,]
        {
            {3 , 2 , 4 },
            {1 , 5 , 7 },
            {8 , 0 , 6 }
        };
        // 使用克隆创建独立数组
        int[,] state = Clone2DArray(firstState);
        int[,] current = Clone2DArray(state);
        ArrayList values = new ArrayList();

        // 先找到0的位置
        int zeroRow = -1;
        int zeroCol = -1;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (current[i, j] == 0)
                {
                    zeroRow = i;
                    zeroCol = j;
                    break;
                }
            }
            if (zeroRow != -1) break;
        }

        // 左移:0的列数大于0才能左移,避免索引越界
        if (zeroCol > 0)
        {
            // 操作current而非state,保证原数组不受影响
            int swap = current[zeroRow, zeroCol - 1];
            current[zeroRow, zeroCol - 1] = 0;
            current[zeroRow, zeroCol] = swap;
            // 克隆后添加到集合,避免后续修改影响集合内元素
            values.Add(Clone2DArray(current));
        }
    }

    static int[,] Clone2DArray(int[,] source)
    {
        int rowCount = source.GetLength(0);
        int colCount = source.GetLength(1);
        int[,] clonedArray = new int[rowCount, colCount];
        
        for (int i = 0; i < rowCount; i++)
        {
            for (int j = 0; j < colCount; j++)
            {
                clonedArray[i, j] = source[i, j];
            }
        }
        return clonedArray;
    }
}

额外说明

原代码中的左移判断逻辑存在问题:current[0,0] != 0 && current[1,0] !=0 && current[2,0] !=0是判断第一列没有0,但左移操作需要0在非第一列(即zeroCol > 0),否则会导致j-1出现索引越界,修复后的代码已经修正了这个逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:12:48