如何设置调试器以捕获更改变量的内容

时间:2017-04-26 19:38:35

标签: c# list visual-studio-debugging

我正在按照此幻灯片和视频实施NEH算法: http://mams.rmit.edu.au/b5oatq61pmjl.pdf https://www.youtube.com/watch?v=TcBzEyCQBxw

我在测试期间遇到的问题是变量Sorted_list被更改了,这导致了我预期的不同结果: 这个部分我有问题,但我不知道它改变了什么(我使用断点和观察变量窗口):

for (int i = 0; i < kmsList.Count; i++)
    {
        for (int j = 0; j < kmsList[i].Length - 1; j++)
        {
            /*
            *
            *   HERE Sorted_list GET MODIFIED UNEXPECTEDLY
            */
            if (i == 0 && j == 0)
                kmsList[0][0] = Sorted_list[0][0];
            else if (i == 0)
                kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
            else if (j == 0)
                kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
        }
    }

完成实施:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FINAL_NEH
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("entre the nmbr of jobs   : ");
            string row = Console.ReadLine();
            Console.WriteLine("entre the nmbr of machines : ");
            string column = Console.ReadLine();

            int job = int.Parse(row.ToString());
            int machine = int.Parse(column.ToString());

            List<int[]> list = new List<int[]>();
            // read the nmbrs and put it in list-----------------------------------------------------  
            for (int i = 0; i < job; i++)
            {
                list.Add(new int[machine + 1]);
                for (int j = 0; j < machine; j++)
                {
                    list[i][j] = int.Parse(Console.ReadLine());
                }

                list[i][list[i].Length - 1] = int.Parse((i + 1).ToString()); //Last Elemnt Is Job Number-
            }

            // show the list----------------------------------------------------------------------------
            for (int i = 0; i < job; i++)
            {
                for (int j = 0; j < machine + 1; j++)
                {
                    Console.Write("\t" + "[" + list[i][j] + "]");
                }

                Console.WriteLine();
            }

            // sort the list------------------------------------------------------------------------------
            for (int i = 0; i < list.Count; i++)
            {
                for (int j = i + 1; j < list.Count; j++)
                {
                    int sumI = 0, sumJ = 0;

                    for (int a = 0; a < list[i].Length - 1; a++)
                    {
                        sumI += list[i][a];
                    }

                    for (int a = 0; a < list[j].Length - 1; a++)
                    {
                        sumJ += list[j][a];
                    }

                    if (sumI < sumJ)
                    {
                        int[] temp = new int[int.Parse(job.ToString())];
                        temp = list[i];
                        list[i] = list[j];
                        list[j] = temp;
                    }
                }


            }

            Console.Write("\n\n-----------------after sorting ------------------------------------\n\n");

            // shaw the list after sorting------------------------------------------
            for (int i = 0; i < job; i++)
            {
                for (int j = 0; j < machine + 1; j++)
                {
                    Console.Write("\t" + "[" + list[i][j] + "]");
                }

                Console.WriteLine();
            }



            // clculate the maxpane of the first 2 jobs---------------------------------------
            List<int[]> initMaxpane = new List<int[]>();
            initMaxpane.Add((int[])list[0].Clone());
            initMaxpane.Add((int[])list[1].Clone());

            // calculer maxspan of  first jobs..............................................
            for (int i = 0; i < initMaxpane.Count; i++)
            {
                for (int j = 0; j < initMaxpane[i].Length - 1; j++)
                {
                    if (j == 0 && i == 0)
                        initMaxpane[0][0] = list[i][j];
                    else if (i == 0)
                        initMaxpane[0][j] = (int)(initMaxpane[0][j - 1] + list[0][j]);
                    else if (j == 0)
                        initMaxpane[i][0] = (int)(initMaxpane[i - 1][0] + list[i][0]);
                }
            }

            for (int i = 1; i < initMaxpane.Count; i++)
            {
                for (int j = 1; j < initMaxpane[i].Length - 1; j++)
                {
                    if ((initMaxpane[i][j - 1] > initMaxpane[i - 1][j]))
                        initMaxpane[i][j] = (int)(initMaxpane[i][j - 1] + list[i][j]);
                    else
                        initMaxpane[i][j] = (int)(initMaxpane[i - 1][j] + list[i][j]);
                }
            }

            int Cmax = initMaxpane[initMaxpane.Count - 1][initMaxpane[initMaxpane.Count - 1].Length - 2];



            Console.WriteLine("\n\n-------the maxpane offirst jobs----------");
            for (int i = 0; i < initMaxpane.Count; i++)
            {
                for (int j = 0; j < initMaxpane[i].Length; j++)
                {
                    Console.Write("\t" + "[" + initMaxpane[i][j] + "]");
                }

                Console.WriteLine();
            }


            List<int[]> initMaxpane2 = new List<int[]>();
            initMaxpane2.Add(list.ElementAt(1));
            initMaxpane2.Add(list.ElementAt(0));

            // calculer maxspan of  first jobs reverse..............................................
            for (int i = 0; i < initMaxpane2.Count; i++)
            {
                for (int j = 0; j < initMaxpane2[i].Length - 1; j++)
                {
                    if (j == 0 && i == 0)
                        initMaxpane2[0][0] = list[i][j];
                    else if (i == 0)
                        initMaxpane2[0][j] = (int)(initMaxpane2[0][j - 1] + list[0][j]);
                    else if (j == 0)
                        initMaxpane2[i][0] = (int)(initMaxpane2[i - 1][0] + list[i][0]);
                }
            }

            for (int i = 1; i < initMaxpane2.Count; i++)
            {
                for (int j = 1; j < initMaxpane2[i].Length - 1; j++)
                {
                    if ((initMaxpane2[i][j - 1] > initMaxpane2[i - 1][j]))
                        initMaxpane2[i][j] = (int)(initMaxpane2[i][j - 1] + list[i][j]);
                    else
                        initMaxpane2[i][j] = (int)(initMaxpane2[i - 1][j] + list[i][j]);
                }
            }

            int Cmax2 = initMaxpane2[initMaxpane2.Count - 1][initMaxpane2[initMaxpane2.Count - 1].Length - 2];
            Console.WriteLine("\n\n-------the maxpane of first jobs (reverse)----------");
            for (int i = 0; i < initMaxpane2.Count; i++)
            {
                for (int j = 0; j < initMaxpane2[i].Length; j++)
                {
                    Console.Write("\t" + "[" + initMaxpane2[i][j] + "]");
                }

                Console.WriteLine();
            }

            List<int[]> MaxpaneList = new List<int[]>();
            if (Cmax > Cmax2)
            {
                MaxpaneList.Add((int[])list[1].Clone());
                MaxpaneList.Add((int[])list[0].Clone());
            }
            else
            {
                MaxpaneList.Add((int[])list[0].Clone());
                MaxpaneList.Add((int[])list[1].Clone());
            }

            List<int[]> bestSequenceList = null;
            List<int[]> kmsList = null;
            List<int[]> Sorted_list = list.ToList();
            int bestCma = 0;
            //int maxspan = 0;

            for (int jo = 2; jo < job; jo++)
            {
                for (int ins = 0; ins <= MaxpaneList.Count; ins++)
                {
                    MaxpaneList.Insert(ins, list[jo]);
                    kmsList = MaxpaneList.ToList();
                    int Cma = 0;
                    for (int i = 0; i < kmsList.Count; i++)
                    {
                        for (int j = 0; j < kmsList[i].Length - 1; j++)
                        {
                            /*
                            *
                            *   HERE Sorted_list GET MODIFIED UNEXPECTEDLY
                            */
                            if (i == 0 && j == 0)
                                kmsList[0][0] = Sorted_list[0][0];
                            else if (i == 0)
                                kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
                            else if (j == 0)
                                kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
                        }
                    }

                    for (int i = 1; i < kmsList.Count; i++)
                    {
                        for (int j = 1; j < kmsList[i].Length - 1; j++)
                        {
                            if ((kmsList[i][j - 1] > kmsList[i - 1][j]))
                                kmsList[i][j] = kmsList[i][j - 1] + Sorted_list[i][j];
                            else
                                kmsList[i][j] = kmsList[i - 1][j] + Sorted_list[i][j];
                        }
                    }

                    Cma = kmsList[kmsList.Count - 1][kmsList[kmsList.Count - 1].Length - 2];
                    Console.WriteLine("\n\n\n------- the maxpane sequence ----------");
                    for (int i = 0; i < MaxpaneList.Count; i++)
                    {
                        for (int j = 0; j < MaxpaneList[i].Length; j++)
                        {
                            Console.Write("\t" + "[" + MaxpaneList[i][j] + "]");
                        }

                        Console.WriteLine();
                    }

                    Console.WriteLine("MAX   : " + Cma + "\n\n\n");
                    if (ins == 0)
                    {
                        bestCma = Cma;
                    }

                    if (jo == 2 && ins == 0)
                    {
                        bestSequenceList = MaxpaneList.ToList();
                        bestCma = Cma;
                    }
                    else
                    {
                        if (bestCma > Cma)
                        {
                            bestSequenceList = MaxpaneList.ToList();
                            bestCma = Cma;
                        }
                    }

                    MaxpaneList.RemoveAt(ins);
                }

                MaxpaneList = bestSequenceList.ToList();
            }

            Console.ReadLine();
        }
    }
}

2 个答案:

答案 0 :(得分:3)

创建列表&lt;&gt;时(或任何其他容器)来自另一个容器(就像调用list.ToList()时一样),您不会创建容器中所有元素的副本。您可以创建对您要复制的列表中的项目的新引用。在CS的说法中,它是一个浅层副本,而不是一个深层副本。

所以,如果你这样做:

        int[] ia = new[] {0, 1, 2, 3, 4};
        int[] ib = new[] {5, 6, 7, 8, 9};
        List<int[]> la = new List<int[]>() { ia, ib };
        List<int[]> lb = la.ToList();

两个列表都引用相同的两个数组,如果你改变一个这样的数组:

        la[1][4] = 10;

然后lb [1] [4]也将是10,因为两个列表每个都包含相同的数组。复制列表不会复制列表中的元素。

答案 1 :(得分:3)

问题在于以下代码(代码段):

List<int[]> Sorted_list = list.ToList();

ToList将创建一个新列表,但因为在这种情况下int []是一个引用类型,所以新列表将包含与原始列表相同的数组的引用。

更新新列表中引用的(数组)值也会影响原始列表中的等效值。

kmsList[0][0] = Sorted_list[0][0];

解决方案是创建'list'及其项目的真实副本(在本例中为int []):

List<int[]> Sorted_list  = list.ConvertAll(myArray => (int[])myArray.Clone());

这段代码将列表中的所有数组克隆到一个新变量Sorted_list。

解释值和引用类型之间差异的有用链接是:https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx

参考类型

引用类型包含指向另一个保存数据的内存位置的指针。

参考类型包括以下内容:

  • 字符串
  • 所有数组,即使它们的元素是值类型Class
  • 类型,例如Form
  • 代表