在C#中,我有一个唯一元素的集合,我想要为每个无序的对有效地执行一些代码。例如,如果我的容器持有{a,b,c},无序对是(a,b),(a,c)和(b,c)。这个问题出现在执行2-opt优化的范围内,因此效率是一个问题。
foreach(容器中的var a){foreach(容器中的var b) { if (a
显然,如果操作符[]可用于获取第一个元素(即,如果底层数据结构是一个列表),则可以很容易地修改它。但是对于所有其他容器,该解决方案依赖于某些比较函数的存在,而且efficient.
ElementAt的解决方案.
编辑:下面是使用的(改进的) LINQ代码:
var x = from a in container
from b in container
where a < b
select new KeyValuePair<int,int>(a,b);
不过,与其他解决方案相比,执行速度要慢3-5倍.
这里的
for(autoit1= container.begin();it1!=container.end();++it1) {autoit2= it1;for(++it2;it2!=container.end();++it2) { //执行代码}
不幸的是,要将其转换为C#,需要克隆(内部使用的)枚举数,语言本身不支持该枚举数。
有谁有更好的主意/解决方案?
发布于 2011-09-11 18:05:31
您是否尝试先将元素复制到列表中,然后使用索引器([i])运算符执行算法?由于该算法具有二次运行时,在其前面有一个线性复制操作是可以忽略不计的。你必须自己找出小型、中型和大型容器的实际运行时.
我认为这可能值得一试,这可能比每次使用比较操作符要快得多。
您还可以检查容器是否为IList<T>类型,并跳过复制操作。
发布于 2011-09-11 18:06:40
如果你不在乎订单,你可以这样做:
int i = 0;
foreach (var a in list)
{
int j = 0;
foreach (var b in list)
{
if (i <= j)
break;
// execute code
j++;
}
i++;
}如果您确实关心订单,您可以将自己限制在实现IList<T>的集合上,该集合包含[]操作符。或者,您可以先将集合复制到List<T>中,然后使用该集合。
发布于 2011-09-11 18:05:21
C#中的枚举数与问题中的C++枚举数不一样。在C#中,您既没有容器的begin元素也没有end元素。您只有Current元素和Next()方法。例如,它允许您产生更多的序列--您可以通过随机数的无穷大序列来枚举,这些序列显然还没有开始或结束。
所以-您不能像在您的C#代码中那样只使用IEnumerable类在IEnumerable中这样做。最好的方法是使用System.Collection.Generics.IList<T>接口。许多类型(如数组)继承此接口。
如果您使用IEnumerable,那么在您的类型中,您(在大多数情况下)迭代一些集合。如果您这样做-您可以实现IList<T>接口。
还有另一种解决方案--在C#列表中,引用类型数组只包含对对象的引用。所以-你可以把你的数据复制到本地列表并使用它操作。但这取决于您的内存和性能要求。
https://stackoverflow.com/questions/7380111
复制相似问题