以下是我用来计算列表中元素的幂集的两段代码
代码1)
public static List<List<int>> getCpower(List<int> list)
{
var result = new List<List<int>>();
for (int i = 0; i < (1 << list.Count); i++)
{
var sublist = new List<int>();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{ sublist.Add(list[j]);
}
}
result.Add(sublist);
}
return result;
}
代码2)
public static List<List<int>> getCpower(List<int> list)
{
var result = new List<List<int>>();var sublist = new List<int>();
for (int i = 0; i < (1 << list.Count); i++)
{
sublist.Clear();sublist.TrimExcess();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{ sublist.Add(list[j]);
}
}
result.Add(sublist);
}
return result;
}
第一个代码使用了一个新语句,如果我试图找出列表的powersets,其数量为30,则会出现OutOfMemoryException。为了节省内存,我使用了Clear()和TrimExcess()来获取列表,就好像它是使用初始化一样code2中的一个新语句。但是这两个代码会返回不同的结果。我不明白为什么会这样。请帮忙。
以下两件作品是不是做同样的事情
for(....)
{
var sublist = new List<int>();
for(......)
{
//some code
}
}
和
var sublist = new List<int>();
for(.....)
{
sublist.Clear();sublist.TrimExcess();
for(.... )
{
//some code
}
}
答案 0 :(得分:5)
在你的第二个代码中,你只有一个嵌套列表 - 你要添加几个引用相同子列表的引用,这是没有意义的。
你有没有考虑过你的第一个代码空间不足的原因可能是因为你从根本上试图一次在内存中保存太多数据?
您可以考虑像这样返回IEnumerable<List<int>>
:
public static IEnumerable<List<int>> getCpower(List<int> list)
{
for (int i = 0; i < (1 << list.Count); i++)
{
var sublist = new List<int>();
for (int j = 0; j < list.Count; j++)
{ if ((i & (1 << j)) != 0)
{
sublist.Add(list[j]);
}
}
yield return sublist;
}
}
现在将对此进行延迟评估 - 因此您可以迭代顶级序列,但除非调用者保留列表,否则您一次只能在内存中有一个列表。
答案 1 :(得分:0)
在第二段代码中,您将清除结果列表。这会改变算法的结果。您正在丢弃结果,因为您正在为所有迭代重用相同的列表实例。
答案 2 :(得分:0)
在第二个代码示例中,您只有一个sublist
实例。每次循环时,相同的实例都会被清除并再次添加到列表中。以下是帮助您理解的示例:
var sublist = new List<int> { 1, 2, 3 };
var result = new List<List<int>> { sublist };
//result[0] is now {1, 2, 3}
sublist.Clear();
//result[0] is now {}
result.Add(sublist);
//result[0], result[1], and sublist are the same instance