c#在大字符集上重复的字符排列

本文关键字:字符 排列 字符集 | 更新日期: 2023-09-27 18:14:01

你好,我试图得到所有可能的组合与给定字符数组的重复。字符数组由字母(只有小写字母)组成,我需要生成长度为30个或更多字符的字符串。

我尝试了许多for循环的方法,但是当我试图在字符串长度大于5的char数组中获得所有char组合时,我得到了内存异常。

所以我创建了类似的方法,只接受第一个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的字符串,但应用程序只是挂起。有更好的方法吗?所有的答案将是非常感激的。提前感谢!

有人可以只是张贴方法它是如何与更大的长度字符串我只是想看到一个例子?我不需要存储这些数据,我只需要将其与其他数据进行比较,然后从内存中释放出来。例如,我用字母表,我不需要整个字母表。问题不是要花多长时间或者有多少种组合!!!!!

c#在大字符集上重复的字符排列

你得到一个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生成字符串的基础上,你可以创建原始值来缓冲和处理字符串的缓冲区。一个简单的解决方案是为。net使用响应式扩展。这里已经有了一个Buffer原语:

  GenerateStrings(3)
    .ToObservable()
    .Buffer(10)
    .Subscribe(list => ... ship the list to another computer and process it ...);

Subscribe中的lambda将被最多包含10个字符串的List<String>调用(调用Buffer时提供的参数)。

除非你有无限多的计算机,否则你仍然需要将计算机从池中取出,并且只有当它们完成计算时才将它们回收到池中。

从对这个问题的评论中可以明显看出,即使您有多台计算机可供使用,您也无法处理26^30个字符串。

我现在没有时间写一些代码,但基本上如果你用完内存使用磁盘。我正在考虑一个线程运行算法来找到组合,另一个线程将结果持久化到磁盘并释放RAM。