控制堆栈溢出的技术?

发布于 2024-11-30 11:56:12 字数 175 浏览 5 评论 0原文

基本上,我的程序将尝试生成所有可能的小写 5 个字母单词的列表。包括所有显然不是真正单词的组合,例如 jshccmmdzq

我通过堆积大量的函数调用来做到这一点,这使得这个词起作用。

但这实在是太多了,我收到了堆栈溢出错误。

有人会如何控制它?

Basically, my program will try to generate the list of all possible lowercase 5-letter words. Including all combinations that clearly are not real words like jshcc or mmdzq.

I do that by stacking up a massive amount of calls for a function, which does the word work.

But that's simply too much, and I get a stack overflow error.

How would someone control that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉墨 2024-12-07 11:56:12

基本上,从递归转换为迭代。通常,这涉及创建一个 Stack 作为“逻辑”堆栈或类似的东西。

然而,我本以为生成所有可能的 5 个字母单词列表的方法只会有一个大约 5 深的堆栈 - 每个字母一个。每个堆栈级别将负责一个字母级别 - 因此堆栈的“顶部”将迭代每个可能的最后一个字母;下一个堆栈帧将迭代所有可能的第四个字母,递归调用该方法以迭代所有可能的最后一个字母等。类似这样的东西(C#代码,但希望你能理解它并将其应用到VB):

const string Letters = "abcdefghijklmnopqrstuvwxyz";

public static List<string> GenerateValidWords(int length)
{
    List<string> words = new List<string>();
    GenerateValidWords(0, new char[length], words);
    return words;
}

private static void GenerateValidWords(int depth, char[] current,
                                       List<string> words)
{
    foreach (char letter in letters)
    {
        current[depth] = letter;
        if (depth == current.Length - 1)
        {
            string word = new string(current);
            if (IsValid(word))
            {
                words.Add(word);
            }
        }
        else
        {
            GenerateValidWords(depth + 1, current, words);
        }
    }
}

现在,如果你不这样做没有任何类型的过滤,这将生成 11,881,376 个单词 - 每个单词 24 字节(在 x86 上)约为 285MB - 加上列表等的所有空间。不应该杀死一台足够大的机器,但它内存相当大。您确定您需要所有这些吗?

Basically, convert from recursion to iteration. Typically that involves creating a Stack<T> as a "logical" stack, or something similar.

However, I'd have expected a method generating a list of all possible 5-letter words to only have a stack about 5 deep - one for each letter. Each stack level would be responsible for one level of letter - so the "top" of the stack would iterate through each possible last letter; the next stack frame down would iterate through every possible fourth letter, calling the method recursively to iterate through all possible last letters etc. Something like this (C# code, but hopefully you can understand it and apply it to VB):

const string Letters = "abcdefghijklmnopqrstuvwxyz";

public static List<string> GenerateValidWords(int length)
{
    List<string> words = new List<string>();
    GenerateValidWords(0, new char[length], words);
    return words;
}

private static void GenerateValidWords(int depth, char[] current,
                                       List<string> words)
{
    foreach (char letter in letters)
    {
        current[depth] = letter;
        if (depth == current.Length - 1)
        {
            string word = new string(current);
            if (IsValid(word))
            {
                words.Add(word);
            }
        }
        else
        {
            GenerateValidWords(depth + 1, current, words);
        }
    }
}

Now if you don't have any sort of filtering, that's going to generate 11,881,376 words - which at 24 bytes each (on x86) is about 285MB - plus all the space for the list etc. That shouldn't kill a suitably big machine, but it is quite a lot of memory. Are you sure you need all of these?

离旧人 2024-12-07 11:56:12

作为一个简单的解决方案,我将使用具有多个循环的迭代方法来生成这些单词:

Dim words As New List(Of String)

Dim first As Integer = Asc("a")
Dim last As Integer = Asc("z")

For one As Integer = first To last
    For two As Integer = first To last
        For three As Integer = first To last
            For four As Integer = first To last
                For five As Integer = first To last
                    words.Add(Chr(one) & Chr(two) & Chr(three) & Chr(four) & Chr(five))
                Next
            Next
        Next
    Next
Next

MsgBox(words.Count)

As a simple solution, I would use an iterative method with multiple loops in order to generate these words:

Dim words As New List(Of String)

Dim first As Integer = Asc("a")
Dim last As Integer = Asc("z")

For one As Integer = first To last
    For two As Integer = first To last
        For three As Integer = first To last
            For four As Integer = first To last
                For five As Integer = first To last
                    words.Add(Chr(one) & Chr(two) & Chr(three) & Chr(four) & Chr(five))
                Next
            Next
        Next
    Next
Next

MsgBox(words.Count)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文