为什么会出现这个错误?

时间:2015-07-10 16:17:15

标签: c++ string recursion

#include <iostream>
#include <string>
using namespace std;
void printinter(string p1, string p2, int m, int n, string output, int i);
int main (void)
{
    string s1,s2,output="";
    cin>>s1>>s2;
    int m = s1.length();
    int n = s2.length();
    int i = 0;
    printinter(s1,s2,m,n,output,1);
    return 0;
}

void printinter(string p1, string p2, int m, int n, string output, int i)
{
    if (m == 0 && n == 0)
    {
        cout<<output<<"\n";
        return;
    }
    else if ( m!= 0)
    {
        //string foo = p1.substr(0,1);
        //cout<<foo<<"\t"; // used for debugging
        output = output + p1.substr(0,1);
        cout<<output<<"\t"; // used for debugging
        printinter(p1.substr(i,m),p2,m-1,n,output,i+1);
    }
    else if (n != 0)
    {
        output = output + p2.substr(0,1);
        printinter(p1,p2.substr(i,n),m,n-1,output,i+1);
    }
}

基本上需要上面的代码来打印两个字符串s1s2的所有交错。现在,我最初在s1s2中输入,并将其传递给函数printinter,该函数通过递归打印交错。基本上,它修复了第一个字符,然后对其余字符进行递归,然后修复另一个字符串的第一个字符,并对其余字符进行递归,每次递减1个单位。最后,它打印输出。

当我尝试运行它时,会出现错误libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string Abort trap: 6

现在,我在过去两个小时内尝试在各个地方放置cout语句以找出错误。但似乎没有任何效果。在使用调试器运行时,它不会在第一次迭代中打印output。我不知道为什么。我不会在这里问过,但是,我不知道错误是什么。我通常自己调试代码,但帮助我这个。谢谢!

3 个答案:

答案 0 :(得分:1)

我很惊讶人们在没有解释原因的情况下投票。如果我不得不猜测,人们会投票,因为代码正在做一些奇怪/不安全的事情,尽管现在我正在把话放在嘴里。

std::string::substr()的文档说明了这一点:

  

如果pos大于字符串长度,则抛出out_of_range异常。

每次递归调用都会缩小传递的字符串的大小,因为substr()会分配一个新的字符串对象:

  

返回一个新构造的字符串对象,其值初始化为该对象的子字符串的副本。

...但是i继续增长,直到它超过传入的字符串的长度。

答案 1 :(得分:1)

我不知道您的原始代码是如何尝试执行以下操作的。但是你对你想要做的事情的描述似乎如下。这是你的意思吗?

#include <iostream>
#include <string>
using namespace std;
void printinter(string p1, string p2,string output);
int main (void)
{
    string s1,s2,output="";
    cin>>s1>>s2;
    printinter(s1,s2,output);
    return 0;
}

void printinter(string p1, string p2, string output)
{
    if (p1.length())
    {
        if (p2.length())
        {
            printinter(p1.substr(1),p2,output+p1[0]);
            printinter(p1,p2.substr(1),output+p2[0]);
        }
        else
        {
            cout << output+p1 << '\n';
        }
    }
    else
    {
        cout << output+p2 << '\n';
    }
}

答案 2 :(得分:0)

我认为你正在尝试这样的事情,但只是让事情变得比他们需要的更复杂。如果那不是你的意思,那么你可能会澄清。您可能实际上有任何额外的复杂性(例如输出字符串)可以很容易地添加回这个简化版本而不会破坏它。

#include <iostream>
#include <string>
using namespace std;
void printinter(string p1, string p2);
int main (void)
{
    string s1,s2,output="";
    cin>>s1>>s2;
    printinter(s1,s2);
    return 0;
}

void printinter(string p1, string p2)
{
    if (p1.length())
    {
        cout << p1[0];
        printinter(p2, p1.substr(1));
    }
    else
    {
        cout << p2;
    }
}