[英]How can I find the Maximum value in List<T> in .Net 2.0?
我想從列表對象中找到最大值。類結構為
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; }
}
}
現在我有找到最大SiteHeight的函數。函數的簽名是
public double FindMaxHeight(List<SiteData> objSite)
{
//logic to find the max. site height
}
我正在使用for循環來識別最大值並面臨性能問題。.NET Framework 2.0-我正在使用
誰能告訴我如何在不使用for循環的情況下找到最大高度? 可能嗎?
我會將對象添加到字典中,從而使我可以更快地按高度排序。
對於所有經典容器,在插入速率和檢索速率之間要進行權衡。
如果很少進行更新,但是您經常依賴最大值,則此策略很有意義。
您需要重寫GetHashCode()以返回具有較高高度的較小數字。
我可以看到一個小困難,如果您的GetHashCode()以這種方式實現,那么您將有重復項。 您將需要確定精度,而不是基於該事實將重復項插入到您的集合中。
或者,我將使用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?
}
}
這是一種奇怪的方式,但是您可以通過遞歸來實現。
您將創建您的初始函數double FindMaxHeight(List<SiteData> objSite)
這將需要調用一個遞歸函數。 遞歸函數是使自身再次被調用的函數,例如
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;
}
}
因此,您可以像這樣遍歷列表,並將(enumerator.Current as SiteData).SiteHeight
與當前獲得的最大高度值進行比較,一旦到達列表末尾,您就可以返回最大值。
正如GregC所說,優化取決於您的常見情況。 如果列表是相當靜態的,並且不經常添加項目,則可以在插入時對列表進行排序。 這會將插入從O(1)轉換為排序算法的復雜性(存在許多O(n log n)算法),並從O(n)檢索到O(1)。 如何使用List<T>.Sort()
我更喜歡將其保留在列表中而不是字典中,因為字典方法為大多數人不期望的哈希碼增加了額外的含義。 由於已經有內置的方法可以對標准化列表進行排序,因此很多人會立即知道。
最簡單的解決方案是使用for循環遍歷列表,並檢查各個條目的最大高度。
另一個可能的解決方案是實現IComparable接口,並根據其高度對所有項目的列表進行排序。 排序后列表中的第一項是您要查找的項。
對於更高級的解決方案,您還可以在指定列表上使用Find方法並指定一個委托,該委托將確定具有最大高度的項目。
希望能幫助到你。
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;
}
}
與列表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;
}
您可以使用此Max方法msdn Max
如果此方法在2.0 .Net中不存在,我認為最好用於
如果您不了解輸入序列的順序,就不可能沒有循環。 向我們顯示您的最高價值搜索代碼,也許可以優化?
如果只想跳過,則可以使用以下方法:
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;
}
或如果有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;
}
但我不知道它是否會比for循環有更好的性能。 我會crono他們,但是很高興知道您的列表將包含多少或至少大約SiteData數量!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.