递归调用溢出

时间:2012-08-29 09:05:06

标签: c++ visual-studio-2008 recursion

在测试数据集上,以下代码有效,但当我更改为具有相似大小的第二个测试集时,它会溢出。

要将一串标记更改为关联的新标记字符串,我使用此向量查找函数

//looks for input string in vector and returns output, 'c' is check row, 'r' is return row
string vectorSearch(string &check, int &direction, int n, int c, int r, int level) 
{
    if ((direction == 1 && check.length() <= 1) || n == list.size()-1 ||(direction == 0 && check.length() > 1)) { //if reading and string is 1 char then pass over
        if (direction == 1){ //convert '???' into '?'
            string temp = "";
            bool wildToken = false;
            for (unsigned int i = 0; i < check.length(); i++) {
                temp+='?';
                if (check.compare(temp) == 0) { check = '?'; wildToken = false; } //done,'???" case, return '?' token
                else if (check[i] == '?') wildToken = true; //not done searching
            }
        }

        return check;
    } else {
        if (list[n][c] == check || list[n][c] == ('0'+check)) //add dummy '0'
            return list[n][r];
        else 
            return vectorSearch (check, direction, n+1, c, r, level);
    }
}

在十几次转换工作正常后,堆栈溢出

从此函数调用vectorSearch

//this function takes an ontology and direction==1 (default) changes from string 
//to single char or if direction==0 takes single char and converts to string representation
string Lexicon::convertOntology(string input, int level, int direction, string out, string temp) 
{
    if (input == "" && temp == "") 
        return out; //check for completed conversion
    else {
        if (direction == 0 || input[0] == '.' || input[0] == '-' || input == "" ) { //found deliniator or end
            if (temp == "") temp = input[0]; //condition for reverse w/o deleniators
            if (input != "") return convertOntology(input.substr(1), level+1, direction, 
                out+=vectorSearch(temp, direction, 0, direction, 1-direction, level));
            else {
                string empty = "";
                return convertOntology(empty, level+1, direction, out+=vectorSearch(temp, direction, 0, direction, 1-direction, level));
            }
        } else 
            return convertOntology(input.substr(1), level, direction, out, temp+=input[0]); //increment and check
    }
}

3 个答案:

答案 0 :(得分:3)

调用堆栈是一种有限的资源,可以像其他任何一样耗尽。函数越大(关于在其中创建的局部变量的创建),每个调用在堆栈上使用的空间量越大。除非你能以某种方式限制递归调用的数量,否则递归是不可避免的。

答案 1 :(得分:3)

在耗尽堆栈空间之前,你只能进行递归。幸运的是,任何递归函数都可以重写为迭代。我相信下面是你的vectorSearch的正确迭代实现,我将把后者留给你。

string vectorSearch(string &check, int &direction, int n, int c, int r, int level) 
{
    while(true)
    {
        if ((direction == 1 && check.length() <= 1) || n == list.size()-1 ||(direction == 0 && check.length() > 1)) { //if reading and string is 1 char then pass over
            if (direction == 1){ //convert '???' into '?'
                string temp = "";
                bool wildToken = false;
                for (unsigned int i = 0; i < check.length(); i++) {
                    temp+='?';
                    if (check.compare(temp) == 0) { check = '?'; wildToken = false; } //done,'???" case, return '?' token
                    else if (check[i] == '?') wildToken = true; //not done searching
                }
            }

            return check;
        } else if (list[n][c] == check || list[n][c] == ('0'+check)) {//add dummy '0'
                return list[n][r];
        }

        n++;
    }
}

答案 2 :(得分:0)

感谢您的评论和评论。

函数很好 - 这个递归函数包要求字符串存在于它所处理的数据库中,并且字符串在这些错误识别特殊条件之前检查并插入一个虚拟字符。在这两个之前有一个递归函数 - 我没有正确地看到我编写了一个包含三个递归函数的集合 - 而且一个是在参数内搜索一个比数据库中存在的字符串更长的字符串;显然参数比堆栈宽。检查参数,一个没有更新,没有控制。

我修复了特殊条件,字符串现在长度相同,搜索参数也是固定的。

发布的功能并不太复杂。