循环遍历列表以有效地找到具有最大数字的对象
本文关键字:数字 对象 列表 遍历 有效地 循环 | 更新日期: 2023-09-27 17:49:30
使用c#,我有一个列表,这些对象都有一个浮动质量,在对象创建时随机化。
遍历列表并找到质量最大的对象的最有效方法是什么?
对于简单列表,最有效的方法是简单的线性时间搜索,如
SomeObject winner;
float maxMass = 0.0f; // Assuming all masses are at least zero!
foreach(SomeObject o in objects) {
if(o.mass > maxMass) {
maxMass = o.mass;
winner = o;
}
}
如果您打算定期这样做,那么按质量排序存储对象和/或使用更合适的存储容器可能是有益的。
听起来像是morelinq中MaxBy/MinBy操作符的完美候选。您可以这样使用它:
objects.MaxBy(obj=>obj.Mass)
实现IComparable将使事情变得简单且易于维护。我已经提供了一个例子。希望这对你有所帮助。我不确定这是否比循环更有效。我知道有时使用linq会在第一次调用时稍微降低性能。
但是很多时候,可维护的代码比轻微的性能增益更重要。有没有人能提供更多关于并行执行和使用AsParallel()循环的性能的细节?
class Program
{
delegate int Del();
static void Main(string[] args)
{
List<MyClass> connections = new List<MyClass>();
connections.Add(new MyClass() { name = "a", mass = 5.001f });
connections.Add(new MyClass() { name = "c", mass = 4.999f });
connections.Add(new MyClass() { name = "b", mass = 4.2f });
connections.Add(new MyClass() { name = "a", mass = 4.99f });
MyClass maxConnection = connections.AsParallel().Max();
Console.WriteLine("{0} {1} ", maxConnection.name, maxConnection.mass);
Console.ReadLine();
}
class MyClass : IComparable
{
public string name { get; set; }
public float mass { get; set; }
public int CompareTo(object obj)
{
return (int)(mass - ((MyClass)obj).mass);
}
}
}
最简单和最有效的解决方案(假设重复查询)是按大小对列表进行排序。
。
private int SortByMass(ObjectWithMass left,ObjectWithMass right)
{
return left.Mass.CompareTo(right.Mass);
}
List<ObjectWithMass> myList = MyFunctionToPopulateTheList();
myList.sort(SortByMass);
一旦列表被排序,第一个元素将是最小的,最后一个元素将是最大的。如果您希望从大到小,可以使用myList.Reverse()
。
运行0 (nlog(n))来排序,然后找到最大的对象是myList[myList.Count -1]
。这是0(1)对于。net列表(它们实际上是数组)
如果您愿意用一点空间换取时间,那么在其中一个实例构造函数中,有如下内容
public Foo(Foo min, Foo max)
{
min = min ?? new Foo();
max = max ?? new Foo();
if(max.mass < this.mass)
max = this;
if(min > this.mass)
min = this;
}
在对象创建时,让调用方法传递这些参数。
Foo min, max = null;
//Create a bunch of Foo objects
var Foos = from n in Enumerable.Range(0, 10000) select new Foo(min, max);