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