Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何修复此代码自身进入的无限循环?_C#_Arrays_Sorting_Bubble Sort - Fatal编程技术网

C# 如何修复此代码自身进入的无限循环?

C# 如何修复此代码自身进入的无限循环?,c#,arrays,sorting,bubble-sort,C#,Arrays,Sorting,Bubble Sort,使用方法制作允许您选择不同搜索/排序方法的程序。对于冒泡排序,当我尝试输出代码底部的数组时,它会打印“System.Int32[]”。此外,代码实际上永远不会结束,它只是打印出“System.Int32[]”和“End of pass 382;”。我该如何阻止这种情况发生? 谢谢 我已经尝试用{0}替换实际的变量名,并在for循环中更改'b

使用方法制作允许您选择不同搜索/排序方法的程序。对于冒泡排序,当我尝试输出代码底部的数组时,它会打印“System.Int32[]”。此外,代码实际上永远不会结束,它只是打印出“System.Int32[]”和“End of pass 382;”。我该如何阻止这种情况发生? 谢谢

我已经尝试用{0}替换实际的变量名,并在for循环中更改'b<_'的值

        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);
            }
        }
int pass\u count=0;
bool=false;
int[]更改_数组=新int[5];
int[]final_数组=新int[5];
int[]起始数组=新int[5];
对于(int a=0;a<5;a++)
{
WriteLine(“输入编号{0}”,(a+1));
更改_数组[a]=Convert.ToInt32(Console.ReadLine());
}
复制(更改数组,最终数组,5);
复制(更改数组,启动数组,5);
数组。排序(最终数组);
while(排序==false)
{
对于(int b=0;b<4;b++)
{
int c=b++;
内部温度;
if(更改_数组[b]>更改_数组[c])
{
temp=更改_数组[b];
更改_数组[b]=更改_数组[c];
更改_数组[c]=temp;
}
其他的
{
继续;
}
}
通过计数++;
if(更改_数组==最终_数组)
{
WriteLine(“排序\n{1}\n到\n{2}、传递计数、起始数组、最终数组需要{0}个过程);
排序=真;
}
其他的
{
WriteLine(“过程结束{0}.\n{1}\n现在是\n{2}”,过程计数,启动数组,更改数组);
}
}
假设最后的数字是“65,34,23,87,30”,我希望它打印“用{0}个过程来排序\n'65,34,23,87,30'\n到\n'23,30,34,65,87',但是它只打印'System.Int32[]和'end of pass'。

使用以下方法:


…而不是尝试输出数组对象本身。

代码中有几个问题

for
循环中,您正在执行以下操作:

int c = b++;
但是,这并不符合您的意愿。它首先将
b
的值赋给
c
,然后将
b
增加1。这意味着这增加了
for
-循环变量,因此,除了
c
b
的值现在被“交换”之外,您基本上跳过了迭代

相反,您需要这样做:

int c = b+1;
这将
c
指定为大于
b
的一个值,并保持
b
不变

最后,您将比较两个阵列实例:

if (changing_array == final_array)
这是行不通的。数组是C#中的引用类型,这只是检查两个变量是否指向内存中的同一位置(它们没有)。相反,您可能希望
SequenceEqual

if (changing_array.SequenceEqual(final_array))
此方法逐个比较两个数组中的项,仅当两个数组的内容相同时才返回true

这些更改后,
while
循环完成

对于输出,不能将数组直接传递到控制台.WriteLine。此方法只能处理简单的数据类型,并且不知道如何输出数组,因此它只写出类型名称。相反,应该将数组转换为整数。最简单的解决方案是
字符串。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));
    }
}
int pass\u count=0;
bool=false;
int[]更改_数组=新int[5];
int[]final_数组=新int[5];
int[]起始数组=新int[5];
对于(int a=0;a<5;a++)
{
WriteLine(“输入编号{0}”,(a+1));
更改_数组[a]=Convert.ToInt32(Console.ReadLine());
}
复制(更改数组,最终数组,5);
复制(更改数组,启动数组,5);
数组。排序(最终数组);
而(!排序)
{
对于(int b=0;b<4;b++)
{
int c=b+1;
内部温度;
if(更改_数组[b]>更改_数组[c])
{
temp=更改_数组[b];
更改_数组[b]=更改_数组[c];
更改_数组[c]=temp;
}
其他的
{
继续;
}
}
通过计数++;
if(更改数组。SequenceEqual(最终数组))
{
WriteLine(“排序\n{1}\n到\n{2}、传递计数、string.Join(“,”,起始数组)、string.Join(“,”,最终数组))需要{0}个过程;
排序=真;
}
其他的
{
WriteLine(“过程{0}的结尾。\n{1}\n现在是\n{2}”、过程计数、字符串.Join(“,”,起始数组)、字符串.Join(“,”,最终数组));
}
}

另请注意,我使用了
!已解决
而不是
solved==false
。两者都是等价的,但第一个版本更常用,也更简洁。

你之所以进入无限循环,是因为你的应用程序中的控件将成为if in sorted==false循环中的其他部分;在这个else中,排序部分仍然为false,因此循环继续

因此,您必须
break
在循环的else部分断开循环,如下图所示,以通过使用break语句防止无限循环,如下图所示。另外,您可以设置
sorted=true,而不是使用break语句,这也将防止无限循环

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
}

浏览代码并添加一些注释可能是最简单的:

    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);
        }
    }
int pass\u count=0;
bool=false;
int[]更改_数组=新int[5];
int[]final_数组=新int[5];
int[]起始数组=新
    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);
        }
    }