简体   繁体   English

我正在尝试用 C++ 编写一个递归函数,它不断导致堆栈溢出

[英]I am trying to write a recursive function in c++ and it keeps causing a stack overflow

So i am trying to write a recursive function to count all of the spaces on a grid of characters.所以我正在尝试编写一个递归函数来计算字符网格上的所有空格。 It is for a project in which i have to write a program that calculates the score of a simplified game of Go.这是一个项目,我必须编写一个程序来计算一个简化的围棋游戏的分数。 The board i'm given looks like this http://pastebin.com/7MaFtmmw[1] .我得到的董事会看起来像这样http://pastebin.com/7MaFtmmw[1] All of the open spaces are surrounded.所有的空地都被包围了。 I am supposed to ultimately find which player surrounded more open space.我应该最终找到哪个玩家包围了更多的空地。 I am not sure how to find how many spaces are surrounded by a specific character.我不确定如何找到被特定字符包围的空格数。 I think i know how to count all of the spaces though.我想我知道如何计算所有的空间。 I wrote this code to do so http://pastebin.com/Pd2ds9fw[2] .我写了这段代码来这样做http://pastebin.com/Pd2ds9fw[2] I call it from an object of the class that it is in that was declared on the stack, like so;我从它所在的类的对象调用它,该对象在堆栈上声明,如下所示; game.countSpaces(0, 0). game.countSpaces(0, 0)。 No matter what, it always causes a stack overflow.无论如何,它总是会导致堆栈溢出。 I have tried debugging it and it never reaches the last two function calls.我试过调试它,但它永远不会到达最后两个函数调用。 It just cycles the first two until visual studio finally crashes.它只是循环前两个,直到 Visual Studio 最终崩溃。 Can anyone explain why this won't work to find the number of spaces?谁能解释为什么这不能找到空格数? Why does it cause the stack to overflow?为什么会导致栈溢出? Also could you give me a hint about how to go after here to count only the spaces one player has surrounded?你也可以给我一个关于如何在这里只计算一个玩家包围的空间的提示吗? If not that's fine.如果没有那很好。 But i really really want to know why my initial space counting function doesn't work.但我真的很想知道为什么我的初始空间计数功能不起作用。 ps I didn't declare count because it is a member of the class. ps 我没有声明 count 因为它是类的成员。

void GoScorer::countSpaces(int row, int col)
{
    if((row < 0) || (row >= BOARDSIZE))
            return;
    if((col < 0) || (col >= BOARDSIZE))
            return;
    if (board[row][col] != ' ')
            return;

    count++;

    countSpaces((row - 1), col);
    countSpaces((row + 1), col);
    countSpaces(row, (col - 1));
    countSpaces(row, (col + 1));
    return;
}

  BWB  BW WB BW    
  BWB  BW WB BW    
  BWBBBBW WB BW    
  BWWWWWW WBBBWWWWW
  BBW  WW WWBBBBBBB
   BWWWWW  WB      
   BBBBBWWWWB      
BBBBB  BBWWWBB BBBB
WWWWB   BW WBBBWWWW
  WWB    BWWWB BW  
  WBBBBBBBWBBBBW   
  WWWWWWWWWB  BW   
  WW   WWWWB  BWWWW
WWWWW     WB  BBBBB
BBBBWWW   WB       
  BBBBW   WB  BBBBB
  BBBBWWW WB  BWWWW
     BBBW WB  BW   
       BW WB  BW

Your countSpaces function will never return.您的countSpaces函数将永远不会返回。 For example, if you start at (2,2), it will recurse to (2, 1) which will then (eventually) recurse to (2, 2) again.例如,如果您从 (2,2) 开始,它将递归到 (2, 1),然后(最终)再次递归到 (2, 2)。

You need to put some sort of check to see if a space has already been counted.您需要进行某种检查以查看是否已经计算了一个空间。 One way would be to have another grid with a flag at each point to say whether this position has been counted already.一种方法是在每个点都有一个带有标志的网格,以说明该位置是否已经被计算在内。

this is one possible solution of other 1000s possible:这是其他 1000 个可能的解决方案之一:

  void GoScorer::countSpaces(int row)
    {
        if((row < 0))
                return;


        count+=std::count(std::begin(board[row]), std::end(board[row]),' ');

        countSpaces(row-1);
        return;
    }

call it :称它为 :

countSpaces(BOARDSIZE-1)

EDIT: if you need a pure recursion method:编辑:如果您需要纯递归方法:

 int count=0;
 void GoScorer::countSpaces(int row, int col)
 {
        if(col < 0){
             if(row>0){
                    countSpaces((row - 1), BOARDSIZE-1);
                    return;
             }

        }
        if(row < 0){
              return;
        }

        if (board[row][col] == ' '){
              ++count;
        }
        countSpaces(row, col - 1);

        return;
 }

call it:称它为:

countSpaces(BOARDSIZE-1,BOARDSIZE-1);

PS not tested PS未测试

Feel free to ask if something is not clear如果有什么不清楚的,请随时询问

In general, a recursive function should always call itself under some condition which can and eventually will be false.通常,递归函数应始终在某些可能并最终为假的条件下调用自身。

There is no point in calling a recursive function (internally) without condition.无条件调用递归函数(内部)是没有意义的。 (But you could conditionally return before the call, making that call conditional) (但您可以在调用之前有条件地返回,使该调用有条件)

You must mark already counted cell, otherwise it'll cycle infinitely.您必须标记已计数的单元格,否则它将无限循环。

For example, it can go left->up->right->down and it'll be in same cell again.例如,它可以向左->向上->向右->向下移动,然后它会再次位于同一个单元格中。

You can add bool table same size and mark each cell:您可以添加相同大小的布尔表并标记每个单元格:

void GoScorer::countSpaces(int row, int col)
{
    if((row < 0) || (row >= BOARDSIZE))
            return;
    if((col < 0) || (col >= BOARDSIZE))
            return;

    if (visited[row][col])
            return;

    if (board[row][col] != ' ')
            return;

    visited[row][col] = true;

    count++;

    countSpaces((row - 1), col);
    countSpaces((row + 1), col);
    countSpaces(row, (col - 1));
    countSpaces(row, (col + 1));
    return;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM