[英]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.