在数组的子集中查找最小值的优雅方法是什么

本文关键字:方法 最小值 是什么 查找 数组 集中 | 更新日期: 2023-09-27 18:35:27

我有一个数组a 100个整数。通过a[70] AND 的最小值的索引查找a[3]最小值的推荐方法是什么?假设没有重复的值。

我知道循环浏览

相关指数范围的笨拙方式:

for(i = 3; i < 70, i++) 
{
    ...
}

我正在寻找一种更优雅的方法来在 C# 中执行此操作,而不是循环。谢谢。

在数组的子集中查找最小值的优雅方法是什么

找出最小值

List<int> templist = a.Skip(3).Take(67).ToList();
int minimum = templist.Min();

对于索引

int index = templist.FindIndex(i => i == minimum) + 3;

我添加了 3,因为列表中的索引将比原始序列中的索引少 3 a.

它在做什么

  1. 跳过 - 保留前 3 个值,即索引 0,1,2 并返回剩余数组。
  2. Take - 从 Skip 返回的数组中,它需要 67 个值。(因为你的 for 循环从 3 开始一直到 70,所以你基本上循环 67 个项目,因为 70 - 3 = 67)。
  3. ToList - 将返回的序列转换为列表以查找索引。
  4. 最小值 - 从中获取最小值。

你必须使用循环,因为它是一个序列。既然你说优雅,所以我用了 LINQ 而不是 for 循环(即使它也这样做循环)。

如果你的数据结构没有排序,那么如果不循环子列表中的所有元素,就无法做到这一点,如果你在提供的API中使用一些隐式循环。

您不能使用排序集合,

因为您正在处理它的子部分(因此您需要为列表的一部分创建一个排序集合),因此无论如何您都必须循环它。

LINQ 的Aggregate不是最简单的,但它可以说是"优雅"解决方案中效率最低的(尽管它们仍然是比直接循环更多的代码行。 此外,遍历自己仍然是最好的,因为您没有分配任何额外的内存)。

但无论如何,如果你觉得有必要让你的继任者把你挂在肖像上,你可以这样做,而不是一个简单的循环:

var minValueAndItsIndex = a
.Skip(3)
.Take(70 - 3)
.Select((value, index) => new { Value = value, Index = index + 3})
.Aggregate((tuple1, tuple2) => (tuple1.Value < tuple2.Value) ? tuple1 : tuple2);

如果创建一个基于 2 项ValueType的元组并使用该元组而不是匿名类型,它将与更高效的直接迭代相当,因为它不会分配任何额外的内存。