如何将对象的唯一副本存储在列表中,在这种情况下是一个半解决的数独单元格的锯齿状数组

Posted

技术标签:

【中文标题】如何将对象的唯一副本存储在列表中,在这种情况下是一个半解决的数独单元格的锯齿状数组【英文标题】:How to store unique copy of object in a list, in this case a semi solved jagged array of sudoku cells 【发布时间】:2019-02-15 14:42:29 【问题描述】:

如何以可以访问先前状态的方式存储数据 (list<list<objects>>)?

这是一个用 c# 编写的数独求解器。我已经尝试生成一个“更高级别”列表(List<List<List<object>>>)并存储在其中,但是似乎这个列表只存储了一个指针或对我的对象的引用,因为后面的更改似乎也会影响存储的实例。

void publics() // only in void for display purpose, acctualy declared in class

    List<List<Cell>> SBoard = new List<List<Cell>>(); // list used in calculations

    List<List<List<Cell>>> BoardListBackup = new List<List<List<Cell>>>(); // list to store SBoards

    int GuessLevel = 0; // to keep track of how many guesses

    void guess()
    
        BoardListBackup.Add(SBoard); // store current board
        Console.WriteLine("stored copy of board");

        for (int i=0;i<9;i++)
        
            for(int j=0;j<9;j++)
            
                if (SBoard[i][j].Value == "0")
                
                    BoardListBackup.Add(SBoard); // possibly saves an instance of list at current state
                    SBoard[i][j].Value = SBoard[i][j].Possibly[0].ToString(); // guess first possible value of first unfilled cell
                    GuessLevel++;
                    UpdatePossibleValues();
                    Console.WriteLine("Guessing [0],[1] = 2", i, j, SBoard[i][j].Possibly[0].ToString());
                    PrintBoardValues();
                    if (error == false)
                    
                        InsertObvious();
                    
                    else if (error == true)
                    
                        Console.WriteLine("Bad guess, reverting board");
                        SBoard = BoardListBackup[GuessLevel - 1]; // what is the problem here??? Board is not rewerting?
                        BoardListBackup.RemoveAt(BoardListBackup.Count-1); // uncertain of syntax here
                        SBoard[i][j].RemovePossible(SBoard[i][j].Possibly[0].ToString()); // remove wrong guess from options
                        GuessLevel--;
                        PrintBoardValues();
                    
                
            
        

当 error == true 时,我希望 SBoard 恢复到 BoardListBackup[GuessLevel-1] 中保存的状态,但它只是保持当前状态。到目前为止,我认为唯一的解决方案是保存为文本文件,但由于我必须同时保存单元格值和单个字符串的可能值,我觉得这将是一个困难的逻辑。

【问题讨论】:

【参考方案1】:

此列表仅存储指向我的对象的指针或引用

除了值类型,大多数实例在底层都是对内存位置的引用。名称可能会更改,但基础参考不会更改。 从技术上讲,一切都是对内存的引用,但 C# 中的引用类型不会改变,而值类型会在改变时获得新的引用位置

我希望 SBoard 恢复到保存状态...

实际保存的是什么状态?没有代码可以进行实际的保存/快照,因为它只进行更新,实际上没有保存任何内容。

如何以可以访问先前状态的方式存储数据(列表>)?

您需要为要存储的类创建一个复制构造函数,并将其存储在 LIFO 堆栈对象中。然后当你需要时,返回,返回/弹出堆栈到你想要的状态。


见C# Stack 让你开始。

【讨论】:

谢谢! LIFO 堆栈似乎真的很有用,但我没有设法正确实现它,假设它也只存储对对象的引用,如果没有配置其他方式。我设法通过添加两个 3d 列表来解决我的问题,我在其中分别存储了可能的值和值。

以上是关于如何将对象的唯一副本存储在列表中,在这种情况下是一个半解决的数独单元格的锯齿状数组的主要内容,如果未能解决你的问题,请参考以下文章

无法将元素插入到列表的向量中

物化视图

Python_实用入门篇_11

打印数组列表

过滤列表:仅获取对象中的唯一元素

SQLAlchemy 中的 Session、sessionmaker、scoped_session