编写程序以查找数组中Max项目的索引

时间:2018-11-30 08:32:12

标签: c# arrays console-application

  

在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;
  }

6 个答案:

答案 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);

参考:C# find highest array value and index

答案 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结合使用的方法,但无法自己使用。