C#数组排序程序中FindIndex返回-1引发越界异常的排查
数组降序排序程序的IndexOutOfRangeException问题分析与修复
问题描述
尝试用C#编写数组数字降序排序程序,代码如下:
//basic number sorter. every number should be on one line and separated by a " " (space). int[] numbers = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); int[] bigToSmall = new int[numbers.Length]; int biggestNum = int.MinValue; for (int y = 0; y < numbers.Length; y++) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] > biggestNum) { biggestNum = numbers[i]; } else if (numbers[i] == biggestNum) { numbers[i] = biggestNum; } } var bigIndx = Array.FindIndex(numbers, row => row == biggestNum); numbers[bigIndx] = 0; bigToSmall[y] = biggestNum; } for (int i = 0; i < bigToSmall.Length; i++) { Console.WriteLine(bigToSmall[i]); }
输入1 2 3时触发System.IndexOutOfRangeException: Index was outside the bounds of the array.异常,使用IndexOf也无法解决。
错误原因
- 索引越界核心诱因:每次找到最大值后,你将对应位置的元素设为
0。当循环到最后一轮时,原数组numbers中的所有元素都被替换成了0,但此时biggestNum仍保留上一轮的最大值(比如输入1 2 3时,最后一轮biggestNum是3)。Array.FindIndex在数组中找不到等于3的元素,会返回-1,随后访问numbers[-1]直接触发索引越界异常。 - 冗余代码无意义:
else if (numbers[i] == biggestNum)分支里的numbers[i] = biggestNum完全多余,只是给元素赋值自身,对逻辑没有任何帮助。
修复方案
方案一:修复原手动排序逻辑
把“找到最大值后设为0”改为“设为int.MinValue”,这样下一轮循环时,这个位置的元素不会被误判为最大值,且最后一轮循环时,biggestNum会被更新为int.MinValue,此时能在数组中找到对应的索引,避免越界。同时移除冗余的else if分支:
//basic number sorter. every number should be on one line and separated by a " ". int[] numbers = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); int[] bigToSmall = new int[numbers.Length]; for (int y = 0; y < numbers.Length; y++) { int biggestNum = int.MinValue; // 每轮循环重新初始化最大值,避免残留上一轮的值 for (int i = 0; i < numbers.Length; i++) { if (numbers[i] > biggestNum) { biggestNum = numbers[i]; } } var bigIndx = Array.FindIndex(numbers, row => row == biggestNum); numbers[bigIndx] = int.MinValue; // 替换为最小值,而非0 bigToSmall[y] = biggestNum; } foreach (int num in bigToSmall) { Console.WriteLine(num); }
方案二:使用内置排序方法(更简洁高效)
如果不需要手动实现排序逻辑,直接用C#内置的排序API,代码更简洁且不易出错:
方法A:Array.Sort + Array.Reverse
int[] numbers = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); Array.Sort(numbers); Array.Reverse(numbers); foreach (int num in numbers) { Console.WriteLine(num); }
方法B:LINQ OrderByDescending
int[] numbers = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); var sortedNumbers = numbers.OrderByDescending(n => n).ToArray(); foreach (int num in sortedNumbers) { Console.WriteLine(num); }
内容的提问来源于stack exchange,提问作者Kaloyan056
相关产品推荐
相关产品推荐

