C# 数组中多个最大值的索引

C# 数组中多个最大值的索引,c#,.net,C#,.net,例如,我有一个数组 int[] array = new int[] {1, 3, 2, 3}; 问题是从数组中获取多个最大值的索引。首先获取最大值: int max = array.Max(); 现在获取具有该值的元素的索引: var indices = array.Select((x, i) => new { Index = i, Value = x }) .Where(x => x.Value == max) .Select(x => x.Index);

例如,我有一个数组

int[] array = new int[] {1, 3, 2, 3};
问题是从数组中获取多个最大值的索引。

首先获取最大值:

int max = array.Max();
现在获取具有该值的元素的索引:

var indices = array.Select((x, i) => new { Index = i, Value = x })
    .Where(x => x.Value == max)
    .Select(x => x.Index);

使用扩展方法,假设您已经拥有要查找的maxValue:

public static IEnumerable<int> AllIndexesOf(this List<T> list, T searchValue)
{
    int minIndex = list.IndexOf(searchValue);
    while (minIndex != -1)
    {
        yield return minIndex;
        minIndex = list.IndexOf(searchValue, minIndex + 1);
    }
}

下面是如何在一个循环中实现这一点

var indices = new List<int>();
int max = int.MinValue;
for(int i = 0; i < array.Length; i++)
{
    if(array[i] > max)
    {
        max = array[i];
        indices.Clear();
    }

    if(array[i] == max)
    {
        indices.Add(i);
    }
}
var索引=新列表();
int max=int.MinValue;
for(int i=0;imax)
{
max=数组[i];
索引。清除();
}
if(数组[i]==max)
{
增加(i);
}
}

基本上,您可以跟踪最大值和索引列表。当您看到一个大于最大值的值时,您将其设置为最大值并清除列表,因为其中的任何索引都不再指向最大值。然后只需检查该值是否等于最大值,如果等于,则将索引添加到列表中。

作为@HimBromBeere答案的计数器

我们可以为每个唯一的数字使用一个字典,然后为它显示的每个索引使用一个整数列表

var intArray = new int[5];
var dictionary = new Dictionary<int, List<int>>();
for (int i = 0; i < intArray.Length; i++)
{
    var num = intArray[i];
    if (!dictionary.ContainsKey(num))
     {
        dictionary.Add(num, new List<int>());
     }

     dictionary[num].Add(i);
}

var max = dictionary.Keys.Max();
return dictionary[max];
var intArray=new int[5];
var dictionary=newdictionary();
for(int i=0;i
这有较少的总体操作,但更简洁。

Linq方法

int[] array = new int[] { 1, 3, 2, 3 };

int[] result = array.Select((x, i) => new { index = i, value = x })
                    .GroupBy(x => x.value)
                    .OrderByDescending(x => x.Key)
                    .First()
                    .Select(x => x.index)
                    .ToArray();

使用
yield return
并在数组中循环,可以执行以下操作:

使用Linq;
使用System.Collections.Generic;
公共静态类IEnumerableExtensions
{
//IEnumerable的扩展方法
公共静态IEnumerable AllIndexOf(此IEnumerable列表,T searchValue)
{
对于(int i=0;i
然后使用LINQ查找数组中的最大值并调用该方法:

使用Linq;//如果尚未存在,请将其包含在文件顶部。
// ...
int[]数组=新的int[]{1,3,2,3};
IEnumerable matchingindex=array.allindexof(array.Max());
//如果需要,请转换为数组
int[]matchingindexasar=matchingIndexes.ToArray();

您可以找到有关扩展方法的更多信息。

您的意思是希望每个实例的所有索引都是唯一的吗?你能编辑一下,让我们看看你到目前为止的尝试吗?考虑到问题的性质,OP可能甚至不知道LINQ是什么,也不能使用它。在回答类似的问题之前,我会一直等到我们得到更多信息。你是对的,我需要显式地迭代键的值是的,我修复了访问max值背后的情况和逻辑。对于对这一点的关注不够,我深表歉意。这一问题的主要问题是,它做的事情超出了需要。如果我真的需要得到不同值的索引,而不仅仅是最大值,我只会创建一个这样的字典。如果列表是十亿个元素呢?在上面的linq语句中,我们将多次迭代整个集合。这里最糟糕的情况是迭代列表一次,以及迭代唯一数字的数量。我同意这很简洁,但客观上并没有更糟——编辑,我在回答这个问题时甚至没有看到你的答案。更简洁!抱歉,您认为您的回答是linq答案
IEnumerable
不包含
IndexOf
的定义。此外,您还需要将方法签名更改为
AllIndexesOf(…)
才能正确工作。除此之外,我真的很喜欢收益率返回所有值的方法。@FelixB.,最初的答案列在列表中,作为收益率的索引。我在没有检查兼容性的情况下更改了它。变量仍然是名称列表。@fubo感谢您的提醒,我更改了代码以包括检查
I
处的值是否与
searchValue
相同
ElementAt
在循环中使用时性能非常好,因为它一次又一次地迭代整个集合。我犯了一个类似的错误,您注意到了。我们倾向于忘记,
IEnumerable
只是等待在lazy中迭代的元素的早午餐。它不了解索引。当您需要使用索引时,您需要支持列表或集合或它们各自的界面等概念的数据结构。
int[] array = new int[] { 1, 3, 2, 3 };

int[] result = array.Select((x, i) => new { index = i, value = x })
                    .GroupBy(x => x.value)
                    .OrderByDescending(x => x.Key)
                    .First()
                    .Select(x => x.index)
                    .ToArray();