【问题标题】:Why this error is taking place?为什么会发生此错误?
【发布时间】:2015-09-29 11:46:42
【问题描述】:
#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。我不知道为什么。我不会在这里问它,但是,我不知道错误是什么。我通常自己调试代码,但请帮我解决这个问题。谢谢!

【问题讨论】:

  • 一个简单的答案有太多错误。最严重的是你没有在递归调用中交换字符串,所以它不会按照你想要的方式交替。但是因为它不交替使用,所以当 i 因在第一个字符串中的使用而增加时,使用 i 作为第二个字符串的索引就会出错。
  • 我建议您简化并仅传递不带索引的子字符串或传递未修改的原始字符串以及索引。通过在嵌套到递归调用中同时修改字符串和索引,您确实需要两次似乎是相同的工作,并且您似乎混淆了您的意图。

标签: c++ string recursion


【解决方案1】:

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

std::string::substr() 的文档是这样说的:

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

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

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

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

【讨论】:

  • 已解决。我使用指向 char 数组的指针而不是字符串。在这种情况下,字符串似乎很难使用。但是,您能告诉我应该做哪些更正才能使其与字符串一起使用吗?
  • 无论你对 char 数组的指针所做的一切都应该可以轻松转换为字符串。
【解决方案2】:

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

#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;
    }
}

【讨论】:

  • 不不,问题是,您的代码只打印输出之一。我必须打印所有交错,其中两个字符串的交错是一个字符串,其中包含两个字符串的所有字符,并且新字符串中字符的相对顺序与原始字符串相同。
  • 此外,我对指向 char 数组方法的指针做了完全相同的事情,它可以工作,但上面的子字符串不行。我想,查找子字符串一定有一些错误。
【解决方案3】:

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

#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';
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多