我想计算字符串数组的幂集(将其视为一组)。当我超过26个元素时,它会出现内存异常。
List<int> ff = new List<int>();
double length = Math.Pow(2, 29);
for (int i = 0; i < length; i++)
{
ff.Add(1);
}
如果你运行它,上面的代码将产生该异常。集合的大小可能会达到1000.因此该集合的功率集大小将为2 ^ 1000。
我该如何处理?
修改:
我知道上面的代码不是电源设置的功能。我只是在检查c#能够容纳多大的数组。
private static Dictionary<int, object> PowerSetB(string[] input)
{
int n = input.Length;
// Power set contains 2^N subsets.
int powerSetCount = 1 << n;
var ans = new Dictionary<int, object>();
for (int setMask = 0; setMask < powerSetCount; setMask++)
{
var s = new ArrayList();
for (int i = 0; i < n; i++)
{
// Checking whether i'th element of input collection should go to the current subset.
if ((setMask & (1 << i)) > 0)
s.Add(input[i]);
}
ans[setMask] = s;
}
return ans;
}
以上代码是我的电源设置功能。</ p>
提前谢谢。
答案 0 :(得分:4)
你真的想将所有项目存储在内存中吗?我建议使用IEnumerable<int>
代替具体化 List<int>
:
// just enumeration, coefficients aren't stored
public static IEnumerable<int> Serie(Func<int, int> coefByIndex) {
if (null == coefByIndex)
throw new ArgumentNullException("coefByIndex");
for (int i = 0; ; ++i)
yield return coefByIndex(i);
}
// Let's sum up all 2**29 values,
// i.e. compute f(1) summing up 2**29 items (it's a long process...)
// sum = 1.44115187606094E+17 (diverges, as we might have expected)
Double sum = Serie(index => index)
.Select(x => x * 1.0)
.Take(1 << 29)
.Sum();
修改:一旦agian,请不要实现(Dictionary<int, object>
)巨大的结果!提供IReadOnlyDictionary<int, int[]>
界面,但不实施为Dictionary<int, object>
,
像这样:
// ArrayList is an obsolete collection;
// int[] far more natural here
public sealed class PowerSet: IReadOnlyDictionary<int, int[]> {
private int m_Power;
private int[] getItem(int index) {
int[] result = new int[m_Power];
for (int i = 0; i < m_Power; ++i) {
result[i] = index % 2;
index /= 2;
}
return result;
}
public PowerSet(int power) {
m_Power = power;
}
public int[] this[int key] {
get {
if (key >= 0 && key < Count)
return getItem(key);
else
throw new ArgumentOutOfRangeException("key");
}
}
public int Count {
get {
return 1 << m_Power;
}
}
public IEnumerable<int> Keys {
get {
return Enumerable.Range(0, Count);
}
}
public IEnumerable<int[]> Values {
get {
return Enumerable.Range(0, Count).Select(index => getItem(index));
}
}
public bool ContainsKey(int key) {
return key >= 0 && key < Count;
}
public IEnumerator<KeyValuePair<int, int[]>> GetEnumerator() {
return Enumerable
.Range(0, Count)
.Select(index => new KeyValuePair<int, int[]>(index, getItem(index)))
.GetEnumerator();
}
public bool TryGetValue(int key, out int[] value) {
if (key >= 0 && key < Count) {
value = getItem(key);
return true;
}
value = null;
return false;
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
...
// Just an easy call
private static IDictionary<int, int[]> PowerSetB(string[] input) {
return new PowerSet(input.Length);
}