你好我试图通过重复给定的char数组获得所有可能的组合。 字符数组由字母组成(仅低于字母),我需要生成长度为30或更多字符的字符串。
我尝试了许多for循环的方法,但是当我尝试在char数组中获取char的所有组合时,字符串的长度超过5,我没有内存异常。
所以我创建了类似的方法,只需要前200000个字符串,然后是2000000,依此类推,这已被证明是成功的,但只有较小的长度字符串。
这是我的方法,长度为7个字符:
public static int Progress = 0;
public static ArrayList CreateRngUrl7()
{
ArrayList AllCombos = new ArrayList();
int passed = 0;
int Too = Progress + 200000;
char[] alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToLower().ToCharArray();
for (int i = 0; i < alpha.Length; i++)
for (int i1 = 0; i1 < alpha.Length; i1++)
for (int i2 = 0; i2 < alpha.Length; i2++)
for (int i3 = 0; i3 < alpha.Length; i3++)
for (int i4 = 0; i4 < alpha.Length; i4++)
for (int i5 = 0; i5 < alpha.Length; i5++)
for (int i6 = 0; i6 < alpha.Length; i6++)
{
if (passed > (Too - 200000) && passed < Too)
{
string word = new string(new char[] { alpha[i], alpha[i1], alpha[i2], alpha[i3], alpha[i4], alpha[i5],alpha[i6] });
AllCombos.Add(word);
}
passed++;
}
if (Too >= passed)
{
MessageBox.Show("All combinations of RNG7 were returned");
}
Progress = Too;
return AllCombos;
}
我尝试以上面描述的方式添加30个for循环,所以我会得到长度为30的字符串,但应用程序只是挂起。有没有更好的方法来做到这一点?所有答案都将非常感谢。提前谢谢!
有人可以直接发布方法如何使用更大的legth字符串我只是想看一个例子吗?我不必存储该数据,我只需要将其与某些内容进行比较并从内存中释放它。我使用字母表例如我不需要整个字母表。问题不是需要多长时间或它会有多少组合!!!!!
答案 0 :(得分:2)
你得到OutOfMemoryException
,因为在循环内你分配一个字符串并将其存储在ArrayList
中。字符串必须保留在内存中,直到ArrayList
被垃圾收集,并且你的循环创建的字符串比你能够存储的字符串多。
如果你只是想检查一个条件的字符串,你应该把检查放在循环中:
for ( ... some crazy loop ...) {
var word = ... create word ...
if (!WordPassesTest(word)) {
Console.WriteLine(word + " failed test.");
return false;
}
}
return true;
然后你只需要存储一个单词。当然,如果循环足够疯狂,它就不会像我们所知的那样在宇宙结束之前终止。
如果需要执行许多嵌套但类似的循环,可以使用递归来简化代码。这是一个效率不高的例子,但至少它很简单:
Char[] chars = "ABCD".ToCharArray();
IEnumerable<String> GenerateStrings(Int32 length) {
if (length == 0) {
yield return String.Empty;
yield break;
}
var strings = chars.SelectMany(c => GenerateStrings(length - 1), (c, s) => c + s);
foreach (var str in strings)
yield return str;
}
调用GenerateStrings(3)
将使用延迟评估生成长度为3的所有字符串(因此字符串不需要额外的存储空间)。
在生成字符串的IEnumerable
之上构建您可以创建primites来缓冲和处理字符串的缓冲区。一个简单的解决方案是使用Reactive Extensions for .NET。这里你已经有一个Buffer
原语:
GenerateStrings(3)
.ToObservable()
.Buffer(10)
.Subscribe(list => ... ship the list to another computer and process it ...);
Subscribe
中的lambda将使用List<String>
调用,最多10个字符串(调用Buffer
时提供的参数)。
除非您拥有无数的计算机,否则您仍然需要从池中提取计算机,并且只有在计算完成后才将它们回收到池中。
从这个问题的评论中可以明显看出,即使您有多台计算机,也无法处理26 ^ 30个字符串。
答案 1 :(得分:-1)
我现在没有时间编写一些代码,但实际上如果你的RAM耗尽,则使用磁盘。我正在思考一个线程运行一个算法来找到组合,另一个线程将结果保存到磁盘并释放RAM。