Как мне исправить бесконечный цикл, в который этот код попадает сам? - PullRequest
0 голосов
/ 23 января 2019

Использование методов для создания программы, которая позволяет выбирать различные методы поиска / сортировки. Для сортировки по пузырькам, когда я пытаюсь вывести массивы в нижней части кода, выводится «System.Int32 []». Кроме того, код на самом деле никогда не заканчивается, он просто печатает 'System.Int32 []' и 'End of pass _'. Как я могу предотвратить это? Спасибо

Я попытался поменять местами {0} для фактических имен переменных и изменить значения 'b <_' в цикле for. </p>

        int pass_count = 0;
        bool sorted = false;
        int[] changing_array = new int[5];
        int[] final_array = new int[5];
        int[] starting_array = new int[5];
        for (int a = 0; a < 5; a++)
        {
            Console.WriteLine("Input number {0}", (a + 1));
            changing_array[a] = Convert.ToInt32(Console.ReadLine());
        }
        Array.Copy(changing_array, final_array, 5);
        Array.Copy(changing_array, starting_array, 5);
        Array.Sort(final_array);



        while (sorted == false)
        {
            for (int b = 0; b < 4; b++)
            {
                int c = b++;
                int temp;
                if (changing_array[b] > changing_array[c])
                {
                    temp = changing_array[b];
                    changing_array[b] = changing_array[c];
                    changing_array[c] = temp;
                }
                else
                {
                    continue;
                }
            }
            pass_count++;
            if (changing_array == final_array)
            {
                Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ",pass_count,starting_array,final_array);
                sorted = true;
            }
            else
            {
                Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ",pass_count,starting_array,changing_array);
            }
        }

Предполагая, что в конце числа равны "65,34,23,87,30", я бы хотел напечатать "Для сортировки потребовалось {0} проходов \ n'65,34,23,87,30 '\ ninto \ n'23,30,34,65,87 '", однако он просто печатает' System.Int32 [] 'и' End of pass _ '.

Ответы [ 4 ]

0 голосов
/ 23 января 2019

Вероятно, проще всего просмотреть код и добавить несколько комментариев:

    int pass_count = 0;
    bool sorted = false;
    int[] changing_array = new int[5];
    int[] final_array = new int[5];
    int[] starting_array = new int[5];
    for (int a = 0; a < 5; a++)
    {
        Console.WriteLine("Input number {0}", (a + 1));
        changing_array[a] = Convert.ToInt32(Console.ReadLine());
    }
    Array.Copy(changing_array, final_array, 5);
    Array.Copy(changing_array, starting_array, 5);
    Array.Sort(final_array);



    while (sorted == false)
    {
        //you should consider having a bool here to track whether a change was made to the array
        //if the for loop runs without making a change, the array is sorted
        for (int b = 0; b < 4; b++) //don't use 4, use changing_array.Length - 1
        {
            int c = b++; //i'd avoid this, because it's potentially confusing as to what b and c values are after it runs. remove use of C and just use b+1 instead
            int temp; //move this into the if, it doesn't need to be out here
            if (changing_array[b] > changing_array[c])
            {
                temp = changing_array[b];
                changing_array[b] = changing_array[c];
                changing_array[c] = temp;
                //you made a change, so set your changeMade bool to true here
            }
            else //this else is totally redundant - the only thing it instructs is to continue looping, which will happen anyway
            {
                continue;
            }
        }
        //test your changeMade Boolean here - if it is false, then set sorted = true
        pass_count++;

        //this isn't how you compare if all the elements of array 1 are in the same order as array 2
        //this is how you compare whether two array variables refer to the same object in memory
        //they don't, so this is always false
        if (changing_array == final_array)
        {
            //this prints Int32[] because when you pass an object into something that
            //needs a string, the runtime calls ToString() on it to make it into a string
            //ToString() isn't anything special for an array, it doesn't print the elements
            //so the default object.ToString() is used, which just prints the type of the object
            //one way to turn an array into a string representation is to say
            //string.Join(",", starting_array)
            //The join method will visit each element, adding them to a comma separated string
            Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ",pass_count,starting_array,final_array);
            sorted = true;
        }
        else //the reason your loop runs forever is because this else always runs, and sorted is never made true
        {
            Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ",pass_count,starting_array,changing_array);
        }
    }
0 голосов
/ 23 января 2019

В вашем коде есть пара проблем.

В цикле for вы делаете:

int c = b++;

Однако это не делает то, что вы намереваетесь . Сначала он присваивает значение b c, а затем увеличивает b на единицу. Это означает, что это увеличивает переменную for -loop, и вы, по сути, пропускаете итерации , благодаря этому, в дополнение к тому факту, что значения c и b теперь "меняются местами".

Вместо этого вам нужно сделать следующее:

int c = b+1;

Это присваивает c значение, большее b, и оставляет b без изменений.

В конце вы сравниваете два экземпляра массива:

if (changing_array == final_array)

Это не будет работать. Массивы являются ссылочными типами в C #, и это просто проверяет, указывают ли обе переменные на одно и то же место в памяти (чего они не делают). Вместо этого вы, вероятно, хотите SequenceEqual:

if (changing_array.SequenceEqual(final_array))

Этот метод сравнивает элементы в двух массивах один за другим и возвращает true, только если оба имеют одинаковое содержимое.

После этих изменений цикл while завершается.

Для вывода вы не можете передать массив в Console.WriteLine напрямую. Этот метод может обрабатывать только простые типы данных и не знает, как вывести массив, поэтому вместо этого он просто записывает имя типа. Вместо этого вы должны превратить массив в целое число. Самым простым решением является метод string.Join:

string.Join(",",starting_array)

Это создаст строку, содержащую элементы массива, разделенные запятой.

Полная версия вашего кода после следующих изменений:

int pass_count = 0;
bool sorted = false;
int[] changing_array = new int[5];
int[] final_array = new int[5];
int[] starting_array = new int[5];
for (int a = 0; a < 5; a++)
{
    Console.WriteLine("Input number {0}", (a + 1));
    changing_array[a] = Convert.ToInt32(Console.ReadLine());
}
Array.Copy(changing_array, final_array, 5);
Array.Copy(changing_array, starting_array, 5);
Array.Sort(final_array);

while (!sorted)
{
    for (int b = 0; b < 4; b++)
    {
        int c = b+1;
        int temp;
        if (changing_array[b] > changing_array[c])
        {
            temp = changing_array[b];
            changing_array[b] = changing_array[c];
            changing_array[c] = temp;
        }
        else
        {
            continue;
        }
    }
    pass_count++;
    if (changing_array.SequenceEqual(final_array))
    {
        Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ", pass_count, string.Join(",",starting_array), string.Join(",", final_array));
        sorted = true;
    }
    else
    {
        Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ", pass_count, string.Join(",", starting_array), string.Join(",", final_array));
    }
}

Также обратите внимание, что я использовал !solved вместо solved == false. Оба варианта эквивалентны, но первая версия более широко используется и более краткая.

0 голосов
/ 23 января 2019

Причина, по которой вы попадаете в бесконечный цикл, заключается в том, что управление в вашем приложении переходит к другой части if внутри отсортированного == ложного цикла;в этой другой части сортировка остается ложной, и цикл продолжается.

Итак, вы должны break выйти из цикла в другой части цикла, как показано ниже, чтобы предотвратить бесконечный цикл с помощью оператора break, как показано вкод ниже.Кроме того, вместо использования оператора break вы можете просто установить sorted = true;, что также предотвратит бесконечный цикл.

if (changing_array == final_array)
{
    Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ", pass_count, starting_array, final_array);
    sorted = true;
}
else
{
    Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ", pass_count, starting_array, changing_array);
    break;//this is what will prevent infinite loop
}
0 голосов
/ 23 января 2019

Используйте строку . Метод Join :

string.Join(",", yourArray)

... вместо попытки вывести сам объект массива.

...