在C#中编写一个控制台应用程序,以在数组中找到索引i,该索引i是数组中的最大数字。
如果数组中的最大元素出现多次,则需要显示最小索引。
如果数组为空,则输出-1。
请告诉我我的代码有什么问题?
例如,如果我输入数组a = { 1, 2, 46, 14, 64, 64 };
,则它返回0
,而它应返回 4
。
public static void Main()
{
double[] a = { 1, 9, 9, 8, 9, 2, 2 };
Console.WriteLine(MaxIndex(a));
}
public static double MaxIndex(double[] array)
{
var max = double.MinValue;
int maxInd = 0, maxCount = 0;
int minIndex = 0;
var min = double.MaxValue;
for (var i = 0; i < array.Length; i++)
{
if (min > array[i])
{
min = array[i];
minIndex = i;
}
if (max == array[i])
maxCount++;
if (max < array[i])
{
maxCount = 1;
max = array[i];
maxInd = i;
}
}
if (array.Length == 0)
return -1;
if (maxCount > 1)
return minIndex;
return maxInd;
}
答案 0 :(得分:8)
您的计算是正确的,但是您返回了错误的变量minIndex
而不是maxIndex
。在一种方法中不要做超出必要的事情。这还会计算最小索引和计数的出现频率,然后对结果不执行任何操作。这是一个精简版:
public static int MaxIndex(double[] array)
{
var max = double.MinValue;
int maxInd = -1;
for (int i = 0; i < array.Length; i++)
{
if (max < array[i])
{
max = array[i];
maxInd = i;
}
}
return maxInd;
}
它还会设置maxInd = -1
,这是您要求的一部分。由于MatthewWatson对在数组中重复double.MinValue
有异议,因此这里是一个优化版本:
public static int MaxIndex(double[] array)
{
if(array.Length == 0)
return -1;
else if (array.Length == 1)
return 0;
double max = array[0];
int maxInd = 0;
for (int i = 1; i < array.Length; i++)
{
if (max < array[i])
{
max = array[i];
maxInd = i;
}
}
return maxInd;
}
如果代码的可读性/可维护性更重要,并且您几乎不关心几毫秒,则可以使用LINQ(仅枚举一次的版本):
int minIndexOfMaxVal = a.Select((num, index) => new {num, index})
.OrderByDescending(x => x.num)
.Select(x => x.index)
.DefaultIfEmpty(-1)
.First();
这不仅适用于数组和双精度数,还适用于各种序列和类型。
答案 1 :(得分:3)
尝试以下简单的代码行:
int[] numbers = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
var index = numbers.ToList().IndexOf(numbers.Max());
我认为代码很简单,可以不言自明。
但是,如果您以性能为目标,则可以省略向List
的转换,并且可以编写自己的代码来查找最大编号的索引。
甚至更简单,由@fubo提出:
Array.IndexOf(numbers, numbers.Max());
答案 2 :(得分:3)
它返回零,因为minIndex确实为零: 将minIndex更改为maxIndex:
if (maxCount > 1) return maxIndex;
为了比较双打,请使用以下代码代替==
:
if (Math.Abs(a-b)<double.Epsilon)
答案 3 :(得分:1)
此代码中可以进行很多简化:
int? maxVal = null; // null because of array of negative value;
int index = -1;
for (int i = 0; i < array.Length; i++)
{
int current = array[i];
if (!maxVal.HasValue || current > maxVal.Value)
{
maxVal = current ;
index = i;
}
}
将使您获得最大值的第一个索引。如果您只需要一个简短的代码并且不介意重复两次,那么一个简单的linq就可以解决问题
var index = array.ToList().IndexOf(array.Max());
答案 4 :(得分:-1)
这不是最迷人的方法,但是有效。
(必须使用System.Linq;)
int maxValue = anArray.Max(); int maxIndex = anArray.ToList()。IndexOf(maxValue);
答案 5 :(得分:-2)
您的代码通常太复杂了,太多的变量无法完成。
您想要第一次出现的索引的最大值,因此除了MaxValueIndex和MaxValue之外,没有任何真正的原因可以存储。
所有其他变量都应为局部变量,以便垃圾回收可以对其进行处理。
对于您的代码实际上有什么问题,我无能为力,因为变量名令我感到困惑。 但是这里有一些代码可以实现您想要实现的目标。
double[] a = { 1, 9, 9, 8, 9, 2, 2 };
var highestValueInArray = a.Max();
var arrayLength = a.Length;
for (int i = 0; i < arrayLength; i++)
{
if (a[i] == highestValueInArray)
{
Console.WriteLine(i);
break;
}
}
您可以使用YourArray.Max()
来获取最大值,而不必手动计算最大值。
然后像通常一样遍历它,但是在第一次出现时,您break;
跳出循环并返回它所在的索引。
我很确定还有一种将FirstOrDefault与IndexOf结合使用的方法,但无法自己使用。