简体   繁体   English

如何在列表中找到最大值 <T> 在.Net 2.0中?

[英]How can I find the Maximum value in List<T> in .Net 2.0?

I want to find the maximum value from the List objects.The class structure is 我想从列表对象中找到最大值。类结构为

         public class SiteData
        {
             #region Fields
            private double? siteHeight;
            private double? siteWidth;

            #endregion



            #region Properties

            public double? SiteHeight
            {
                    get { return siteHeight; }
                    set { siteHeight = value; }
            }

            public double? SiteWidth
            {
                get { return siteWidth; }
                    set { siteWidth = value; }
            }
    }

Now i am having the function to find the Maximum SiteHeight.The signature of the function is 现在我有找到最大SiteHeight的函数。函数的签名是

              public double FindMaxHeight(List<SiteData> objSite)
              {
               //logic to find the max. site height
               }

I am using for loop to identify the maximum value and facing the performance issue.... .Net framework 2.0 - i am using right now 我正在使用for循环来识别最大值并面临性能问题。.NET Framework 2.0-我正在使用

Can anyone tell me how to find the maximum height without using for loop? 谁能告诉我如何在不使用for循环的情况下找到最大高度? is it possible? 可能吗?

I'd add objects into a dictionary, that allows me to sort by height faster. 我会将对象添加到字典中,从而使我可以更快地按高度排序。

With all classic containers, there is a trade-off between rate of insertion and rate of retrieval. 对于所有经典容器,在插入速率和检索速率之间要进行权衡。

This strategy makes sense when updates are rare, but you rely on the max value frequently. 如果很少进行更新,但是您经常依赖最大值,则此策略很有意义。

You'd need to override GetHashCode() to return smaller numbers with larger heights. 您需要重写GetHashCode()以返回具有较高高度的较小数字。

I can see a little difficulty in that you'll have duplicates if your GetHashCode() is implemented that way. 我可以看到一个小困难,如果您的GetHashCode()以这种方式实现,那么您将有重复项。 You'll need to decide on precision, and not insert duplicates into your collection based on that fact. 您将需要确定精度,而不是基于该事实将重复项插入到您的集合中。

Alternately, I'd use MultiDictionary from PowerCollections , and then rely on linear search pattern for the few readouts that are in the topmost bin. 或者,我将使用PowerCollections中的 MultiDictionary,然后依赖线性搜索模式来搜索位于最顶层bin中的少数读数。

internal int IndexForSortingBySiteHeight
{
   get
   {
      if(double.IsNaN(siteHeight) throw new ApplicationException();

      return (int)Math.Floor(siteHeight);
   }
}

public class ContainerForSortingBySiteHeight
{
    private List<SiteData> siteDataItems;

    public void Add(SiteData datum)
    {
        if(datum == null) return;

        siteDataItems[datum.IndexForSortingBySiteHeight] = datum;
    }

    public Max
    {
       get { return siteDataItems[0]; } // here's why a list won't work! What index should i use?
    }
}

It's rather a strange way to do it, but you could do it with recursion. 这是一种奇怪的方式,但是您可以通过递归来实现。

You would create your initial function double FindMaxHeight(List<SiteData> objSite) 您将创建您的初始函数double FindMaxHeight(List<SiteData> objSite)

This would need to call a function that is a recursive function. 这将需要调用一个递归函数。 A recursive function is one that causes itself to be called again, eg 递归函数是使自身再次被调用的函数,例如

int EnumerableLength(IEnumerable<T> enumerable)
{
    IEnumerator<T> enumerator = enumerable.GetEnumerator();
    return EnumeratorCount(enumertor, 0);
}

int EnumeratorCount(IEnumerator<T> enumerator, int count)
{
    if(enumerator.MoveNext())
    {
        count++;
        return EnumeratorCount(enumerator, count);
    }
    else
    {
        return count;
    }
}

So you could move through your list like this, and comparing (enumerator.Current as SiteData).SiteHeight to the max height value you've currently got, and once you reach the end of the list you can return whatever the max is. 因此,您可以像这样遍历列表,并将(enumerator.Current as SiteData).SiteHeight与当前获得的最大高度值进行比较,一旦到达列表末尾,您就可以返回最大值。

As GregC said, the optimization depends on what your common case is. 正如GregC所说,优化取决于您的常见情况。 If the list is fairly static and does not have item added often, you can sort the list on insertion. 如果列表是相当静态的,并且不经常添加项目,则可以在插入时对列表进行排序。 This flips insertion from O(1) to the complexity of your sort algorithm (there are a number of O(n log n) algorithms) and retrieval from O(n) to O(1). 这会将插入从O(1)转换为排序算法的复杂性(存在许多O(n log n)算法),并从O(n)检索到O(1)。 How to use List<T>.Sort() 如何使用List<T>.Sort()

I prefer keeping it in a list as opposed to a dictionary because the dictionary method adds extra meaning to the hashcode that most people won't expect. 我更喜欢将其保留在列表中而不是字典中,因为字典方法为大多数人不期望的哈希码增加了额外的含义。 Where as there are already built-in methods to sort a list that are standardized and many people will know immediately. 由于已经有内置的方法可以对标准化列表进行排序,因此很多人会立即知道。

The simplest solution would be iterating over the list using a for loop and checking the individual entries for the maximum height. 最简单的解决方案是使用for循环遍历列表,并检查各个条目的最大高度。

Another possible solution would be to implement the IComparable interface and sort the list of all items according to its height. 另一个可能的解决方案是实现IComparable接口,并根据其高度对所有项目的列表进行排序。 The first item in the list after the sorting is the one you are looking for. 排序后列表中的第一项是您要查找的项。

For a more advanced solution you could also use the Find method on the specified list and specify a delegate that will determine the item with the maximum height. 对于更高级的解决方案,您还可以在指定列表上使用Find方法并指定一个委托,该委托将确定具有最大高度的项目。

Hope it helps. 希望能帮助到你。

public class SiteData
{
    private double? siteHeight;
    private double? siteWidth;

    public double? SiteHeight
    {
        get { return siteHeight; }
        set { siteHeight = value; }
    }

    public double? SiteWidth
    {
        get { return siteWidth; }
        set { siteWidth = value; }
    }

    public static double FindMaxHeight(List<SiteData> objSite)
    {
        objSite.Sort(delegate(SiteData s1, SiteData s2) 
                                  {
                                      if (s1.SiteHeight > s2.SiteHeight)
                                          return 1;

                                      if (s1.SiteHeight < s2.SiteHeight)
                                          return -1;

                                      return 0;
                                  });
        return objSite[objSite.Count - 1].SiteHeight.Value;
    }
}

With List T: 与列表T:

    public static double FindMaxHeight<T>(List<T> objSite)
            where T : SiteData
    {
        objSite.Sort(delegate(T s1, T s2) 
                                  {
                                      if (s1.SiteHeight > s2.SiteHeight)
                                          return 1;

                                      if (s1.SiteHeight < s2.SiteHeight)
                                          return -1;

                                      return 0;
                                  });
        return objSite[objSite.Count - 1].SiteHeight.Value;
    }

you can use this Max method msdn Max 您可以使用此Max方法msdn Max

if this method doesn't present in 2.0 .Net I think is better to use for 如果此方法在2.0 .Net中不存在,我认为最好用于

It's not possible without loop if you have no kwnoledge about order of input sequence. 如果您不了解输入序列的顺序,就不可能没有循环。 Show us your max value search code, maybe optimization is possible? 向我们显示您的最高价值搜索代码,也许可以优化?

If you only want to skip the for you can use the following method: 如果只想跳过,则可以使用以下方法:

public double FindMaxHeight(List<SiteData> objSite)
        {
            objSite.Sort(new Comparison<SiteData>((x, y) => y.SiteHeight.Value.CompareTo(x.SiteHeight.Value)));
            return  objSite.Count > 0 ?  objSite[0].SiteHeight.Value : 0;
        }

or this one if there can be SiteData withoud siteHeight value 或如果有SiteHeight值的SiteData,则为此值

public  double FindMaxHeight(List<SiteData> objSite)
        {
            objSite.Sort(new Comparison<SiteData>((x, y)
                =>
                {
                    int xHeight, yHeight;
                    yHeight = y.SiteHeight.HasValue ? y.SiteHeight.Value : 0;
                    xHeight = x.SiteHeight.HasValue ? x.SiteHeight.Value : 0;
                    return yHeight.CompareTo(xHeight);
                }
            ));
            return  objSite.Count > 0 ?  objSite[0].SiteHeight.Value : 0;
        }

but I don't know if it will have better performance that the for loop. 但我不知道它是否会比for循环有更好的性能。 I will crono them, but it will be nice to know, how big or at least the approximate number of SiteData that your list will have! 我会crono他们,但是很高兴知道您的列表将包含多少或至少大约SiteData数量!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM