循环遍历列表,高效找到编号最大的对象!

发布于 2024-10-31 03:20:22 字数 76 浏览 9 评论 0原文

使用 C# 我有一个列表,这些对象都有一个在创建对象时随机化的浮动质量。

循环列表并找到质量最大的物体的最有效方法是什么?

using c# i have a list those objects all have a float mass that is randomized when the object is created.

Whats the most efficient way to loop through the list and find the object with the highest mass?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

十秒萌定你 2024-11-07 03:20:22

使用简单列表执行此操作的最有效方法是简单的线性时间搜索,如

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

如果这是您打算定期执行的操作,则按质量排序的顺序存储对象和/或使用更合适的储存容器。

The most efficient way to do this with a simple list will be a simple linear time search, as in

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

If this is something you intend to do regularly, it may be beneficial to store your objects in an order sorted by mass and/or to use a more appropriate storage container.

一抹微笑 2024-11-07 03:20:22

听起来像是 morelinq 中 MaxBy/MinBy 运算符的完美候选者。您可以按如下方式使用它:

objects.MaxBy(obj=>obj.Mass)

Sounds like a perfect candidate for the MaxBy/MinBy operators in morelinq. You could use it as follows:

objects.MaxBy(obj=>obj.Mass)
居里长安 2024-11-07 03:20:22

实现 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);
        }
    }
}

Implementing IComparable would make things simple and easy to maintain. I have provided an example. Hope this helps.
I am not sure if this is more efficient than looping. I understand that sometimes using linq slightly degrades the performance for the first time when it is invoked.

But definitely many a times maintainable code scores more over slight performance gain. Can someone provide more details on performance of PARALLEL execution vs looping with 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);
        }
    }
}
酒浓于脸红 2024-11-07 03:20:22

最简单、最有效的解决方案(假设重复查询)是按大小对列表进行排序。

private int SortByMass(ObjectWithMass left,ObjectWithMass right)
{
  return left.Mass.CompareTo(right.Mass);
}    
List<ObjectWithMass> myList = MyFunctionToPopulateTheList();
myList.sort(SortByMass);

一旦列表排序,第一个元素将是最小的,最后一个元素将是最大的。
如果您希望按从大到小的顺序排列,可以使用 myList.Reverse()。

它运行在 o(nlog(n)) 中进行排序,然后找到最大的对象是 myList[myList.Count -1]。对于 .net 列表来说是 o(1) (它们实际上是下面的数组)

The simplest and most efficient solution (assuming repeated queries) is to sort the list by size.

i.e.

private int SortByMass(ObjectWithMass left,ObjectWithMass right)
{
  return left.Mass.CompareTo(right.Mass);
}    
List<ObjectWithMass> myList = MyFunctionToPopulateTheList();
myList.sort(SortByMass);

Once the list is sorted, the first element will be the smallest, and the last will be the largest.
You can use myList.Reverse() if you want it by largest to smallest.

This runs in o(nlog(n)) to sort, and then finding the largest object is myList[myList.Count -1]. which is o(1) for .net lists (they are actually arrays underneath)

岁月苍老的讽刺 2024-11-07 03:20:22

如果您愿意用一点空间来换取时间,那么在一个实例构造函数中,可以使用如下所示的内容

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

If you're willing to trade a little space for time then, in one of the instance constructors, have something like the following

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

And upon object creation have the calling method pass those paramters.

Foo min, max = null;

//Create a bunch of Foo objects

var Foos = from n in Enumerable.Range(0, 10000) select new Foo(min, max);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文