C # Список Манипуляция - Выходной отличается при переходе по сравнению с бегом - PullRequest
1 голос
/ 13 марта 2011

Я новичок в C #, и я действительно растерялся из-за того, что пытаюсь сделать для проекта в классе C #.

Назначение - это некоторая манипуляция со списком в C #.

Программа принимает список элементов в текстовом поле, затем перебирает эти элементы, создавая несколько копий списка.Он случайным образом изменяет размер каждой копии списка от 3 до всех элементов.Затем он выводит все копии.

Проблема, с которой я столкнулся, заключается в том, что когда я выполняю эту программу с помощью отладчика, я получаю ожидаемый результат.То же самое происходит, если я отображаю окно сообщения после каждой итерации (как в коде ниже).

Однако, если я просто запускаю программу напрямую, я получаю другой вывод.Вместо вариаций в списках все копии списка одинаковы.

Если вы видите в коде, который я прокомментировал, «// FIRST DEBUG MESSAGEBOX» и «// SECOND DEBUG MESSAGEBOX».Если код первого сообщения отладки оставлен там, вывод будет таким, как ожидалось ... выводятся несколько версий списка со случайными длинами от 3 до всех элементов.

Однако, и именно здесь ясбит с толку ... если вы закомментируете первый код отладочного сообщения, вы получите другой результат.Все версии вывода списка имеют одинаковую длину без изменений.

Любая помощь приветствуется!Вот код, который у меня есть ... извините, если это ужасно - я новичок в C #:

public partial class MainForm : Form
{
    /**
     * Vars to hold raw text list items
     * and list items split by line
     */
    String rawListItems = "";
    List<string> listItems = new List<string>();
    List<List<string>> textListItems = new List<List<string>>();

    public MainForm()
    {
        InitializeComponent();
    }

    private void cmdGo_Click(object sender, EventArgs e)
    {
        // store the contents of the list item text box
        this.rawListItems = txtListItems.Text;
        this.listItems.AddRange(Regex.Split(this.rawListItems, "\r\n"));

        // setup min and max items - max items all items
        int minItems = 3;
        int maxItems = this.listItems.Count;

        // We'll copy this list X times, X = same number of items in list
        for (int i = 0; i < this.listItems.Count; i++)
        {
            // make a copy of the list items
            List<string> listItemsCopy = new List<string>(this.listItems);

            // get a random number between min items and max items
            Random random = new Random();
            int maxIndex = random.Next(minItems, maxItems + 1);    // max is exclusive, hence the +1

            // remove all elements after the maxIndex
            for (int j = 0; j < listItemsCopy.Count; j++)
            {
                if (j > maxIndex)
                {
                    listItemsCopy.RemoveAt(j);
                }
            }

            // add the list copy to the master list
            this.textListItems.Add(listItemsCopy);

            // FIRST DEBUG MESSAGEBOX
            String tst = "";
            foreach (string item in listItemsCopy)
            {
                tst += item + " ## ";
            }
            MessageBox.Show(tst);
        }

        // SECOND DEBUG MESSAGEBOX
        String output = "";
        foreach (List<string> listitem in this.textListItems)
        {
            foreach (string item in listitem)
            {
                output += item + " ## ";
            }
        }
        MessageBox.Show(output);
    }
}

Ответы [ 3 ]

2 голосов
/ 13 марта 2011

Переместить создание Random из цикла:

Random random = new Random();

По умолчанию конструктор использует начальное время по умолчанию.В узком цикле вы можете получать «один и тот же» генератор случайных чисел вместо другого генератора с каждым циклом.

При использовании MessageBoxes или одиночного пошагового выполнения вы позволяете таймеру работать и получать «новый»генератор случайных чисел в каждом цикле.

0 голосов
/ 13 марта 2011

В тех случаях, когда пошаговое выполнение кода в отладчике влияет на поведение программы, полезным альтернативным методом отладки является использование пространства имен System.Diagnostics , в частности класса Trace .

Функции Trace работают так же, как Console.WriteLine (), вы можете отслеживать строку или строку формата, а также массив объектов для заполнения строки формата, например:

Trace.TraceInformation("some message that tells me something");

Trace.TraceInformation("some useful format string {1}, {0}", 
    new object[] {someObject, someOtherObject});
0 голосов
/ 13 марта 2011

Я не совсем понимаю ваше назначение, но этот цикл кажется неправильным:

   for (int j = 0; j < listItemsCopy.Count; j++)
   {
       if (j > maxIndex)
       {
           listItemsCopy.RemoveAt(j);
       }
   }

, когда вы удаляете элемент в середине списка, элементы после этого сдвигаются, поэтому не всеэлементы после maxIndex удаляются, как и следовало ожидать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...