如何将递归函数转换为迭代函数

发布于 2025-01-21 01:46:27 字数 914 浏览 0 评论 0原文

我正在尝试使用堆栈将此递归函数转换为迭代函数:

void GetToTownRecursive(int x, Country &country, AList *accessiblesGroup, vector<eTownColor> &cities_colors)
{

    cities_colors[x - 1] = eTownColor::BLACK;
    accessiblesGroup->Insert(x);

    List *connected_cities = country.GetConnectedCities(x);
    if (!connected_cities->IsEmpty())
    {
        ListNode *curr_city = connected_cities->First();
        while (curr_city != nullptr)
        {
    
            if (cities_colors[curr_city->GetTown() - 1] == eTownColor::WHITE)
            {
                GetToTownRecursive(curr_city->GetTown(), country, accessiblesGroup, cities_colors);
            }
            curr_city = curr_city->GetNextNode();
        }
    }
}

该函数将城镇编号作为输入,并返回与该城镇连接(直接和间接)的城镇列表。

由于递归调用后采取的唯一操作是提升列表迭代器 - curr_city,因此我在转换它时遇到了困难。在这种情况下我应该将什么推入堆栈?

很高兴得到您的帮助!

I'm trying to convert this recursive function to an iterative one using a stack:

void GetToTownRecursive(int x, Country &country, AList *accessiblesGroup, vector<eTownColor> &cities_colors)
{

    cities_colors[x - 1] = eTownColor::BLACK;
    accessiblesGroup->Insert(x);

    List *connected_cities = country.GetConnectedCities(x);
    if (!connected_cities->IsEmpty())
    {
        ListNode *curr_city = connected_cities->First();
        while (curr_city != nullptr)
        {
    
            if (cities_colors[curr_city->GetTown() - 1] == eTownColor::WHITE)
            {
                GetToTownRecursive(curr_city->GetTown(), country, accessiblesGroup, cities_colors);
            }
            curr_city = curr_city->GetNextNode();
        }
    }
}

The function takes a town number as an input and returns a list of towns that are connected to that town (directly as well as indirectly).

I'm having difficulty converting it because of the while loop within and because the only action taken after the recursive call is the promotion of the list iterator - curr_city. What should I push into the stack in this case?

Would be glad for your help!

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

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

发布评论

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

评论(2

遇到 2025-01-28 01:46:27

递归呼叫后采取的动作是整个While循环的剩余时间(所有剩余的迭代)。在堆栈上,您必须节省任何在递归电话期间可能会更改的变量,但需要之后需要。在这种情况下,这仅仅是curr_city的值。

如果goto仍然是一件事情,则可以用以下方式替换递归调用:

  1. save curr_city
  2. set x = curr_city-&gt; gettown()
  3. goto 从结束开始

,您必须

  1. 检查堆栈
  2. ,如果保存curr_city,将其还原并在(3)之后恢复并goto,

因为它是不可接受的可接受此类gotos事物(它们使您的代码难以理解),您必须将功能分解为3个顶级部分:

  • 第1部分:第一个递归电话之前的所有内容,以1-3
  • 第2部分:一个循环 结束递归呼叫之间的所有内容,如果到另一个递归电话,则以1-3结尾,如果没有进行4-5。
  • 第3部分:上次递归呼叫之后发生的任何事情,在这种情况下,这是什么都没有的。

通常,在重新排列后,您可以进行大量的清理和简化。

The action taken after the recursive call is the whole remainder of the while loop (all the remaining iterations). On the stack, you have to save any variables that could change during the recursive call, but will be needed after. In this case, that's just the value of curr_city.

If goto was still a thing, you could then replace the recursive call with:

  1. save curr_city
  2. set x = curr_city->GetTown()
  3. goto start

Then at the end, you have to

  1. check stack
  2. If there's a saved curr_city, restore it and goto just after (3)

Because it's not acceptable to use gotos for this sort of thing (they make your code hard to understand), you have to break up your function into 3 top-level parts:

  • part 1: all the stuff before the first recursive call, ending with 1-3
  • part 2: a loop that does all the stuff between recursive calls, ending with 1-3 if it gets to another recursive call, or 4-5 if it doesn't.
  • part 3: anything that happens after the last recursive call, which is nothing in this case.

Typically there is then a lot of cleanup and simplification you can do after this rearrangement.

疾风者 2025-01-28 01:46:27

基本想法将是以下内容。

void GetToTown(int x, Country &country, AList *accessiblesGroup,
   vector<eTownColor> &cities_colors)
{
    Stack<int> pendingX = new ...
      
    pendingX.push(x);
    
    while (!pendingX.isEmpty()) {
        int localX = pendingX.Pop();
        cities_colors[localX - 1] = eTownColor::BLACK;
        accessiblesGroup->Insert(localX);
        
        List *connected_cities = country.GetConnectedCities(localX);
        if (!connected_cities->IsEmpty())
        {
            ListNode *curr_city = connected_cities->First();
            while (curr_city != nullptr)
            {            
                if (cities_colors[curr_city->GetTown() - 1] == nColor::WHITE)
                {
                    pendingX.Push(curr_city->GetTown());
                }
                curr_city = curr_city->GetNextNode();
            }
         }
    }
}

The basic idea would be something like the following.

void GetToTown(int x, Country &country, AList *accessiblesGroup,
   vector<eTownColor> &cities_colors)
{
    Stack<int> pendingX = new ...
      
    pendingX.push(x);
    
    while (!pendingX.isEmpty()) {
        int localX = pendingX.Pop();
        cities_colors[localX - 1] = eTownColor::BLACK;
        accessiblesGroup->Insert(localX);
        
        List *connected_cities = country.GetConnectedCities(localX);
        if (!connected_cities->IsEmpty())
        {
            ListNode *curr_city = connected_cities->First();
            while (curr_city != nullptr)
            {            
                if (cities_colors[curr_city->GetTown() - 1] == nColor::WHITE)
                {
                    pendingX.Push(curr_city->GetTown());
                }
                curr_city = curr_city->GetNextNode();
            }
         }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文