【问题标题】:Remove Consecutive Duplicates Recursively giving infinite recursion以递归方式删除连续重复项,以提供无限递归
【发布时间】:2018-12-10 12:20:32
【问题描述】:

不是作业问题。 我是自学的。 我必须通过递归删除字符串中的连续字符。但是,我制作的程序不适用于包含重复项的输入。它正在进行无限递归,因此会产生分段错误。但是,它适用于其中没有连续重复的输入。我曾尝试在 Eclipse Ide 中进行调试,但调试时事情变得很奇怪。 (我知道如何调试)但是当我调试和运行时我无法弄清楚事情是不同的。我会在我的代码之后给你例子。

#include <iostream>
#include <cstring>
using namespace std;

void removeConsecutiveDuplicates(char *input) {
    int l = strlen(input);
    if(l == 0) {
      return;
    }
    if(input[0] != input[1]) {
        removeConsecutiveDuplicates(input+1);
        return;
    }
    int i = 1;
    for(; input[i] != '\0'; ++i) {
      input[i-1] = input[i];
    }
    input[i] = '\0';
    removeConsecutiveDuplicates(input);
}
int main(void) {
    char ch[1000];
    cin >> ch;
    cout<<"The String Before Removing Duplicates : "<<ch<<endl;
    removeConsecutiveDuplicates(ch);
    cout<<"The String After Removing Duplicates : "<<ch<<endl;
    return 0;
}

当我调试这段代码时,我看到变量 l 的值是 16。这在运行时不会发生。我在这里缺少什么?

【问题讨论】:

  • 你的代码的输入是什么?你真的应该在 C++ 中使用 std::string 而不是 char ch[1000]
  • 输入:abc O/p:abc 输入:aabccde O/P:abcde
  • 递归调用在这里并没有真正帮助您的代码。你可以环顾四周。应该避免递归是可能的。如果您将其作为练习,那么我将用 memmove 替换 for 循环。循环看起来有点奇怪。通常 i 的初始化在 for 之后。我希望在这里待一段时间。可能会做一段时间。是否需要写入空字符,因为无论如何它都是退出循环的条件。尝试添加 if(input[i] != '\0'),我怀疑它永远不会触发并且可以删除。
  • c++: string text; cin &gt;&gt; text; cout &lt;&lt; "Before : " &lt;&lt; text &lt;&lt; "\n"; text.erase(std::unique(text.begin(), text.end()), text.end()); cout &lt;&lt; "After : " &lt;&lt; text &lt;&lt; "\n";
  • 在 C++ 中,你可以使用*std::unique(input, input + strlen(input)) = '\0';

标签: c++ arrays pointers recursion char


【解决方案1】:

要通过你自己分配的作业问题:),请解释为什么以下行在你的代码中从来没有任何影响:

input[i] = '\0';

【讨论】:

  • 在这里得到它。这条线没有做任何改变
【解决方案2】:

在你的函数中,改变这个:

input[i] = '\0';

到这里:

input[i-1] = '\0';

因为你已经砍掉了一个字符,所以你应该减小你的字符串的大小。

否则,您将无法减小大小,因此在不改变大小的情况下一遍又一遍地循环相同大小,将导致无限循环(因为大小不会改变)。


我建议你下次使用std::string,因为这是 C++。

【讨论】:

  • 但是为什么这在这里工作? geeksforgeeks.org/remove-consecutive-duplicates-string我刚刚用上面的网站答案替换了函数的定义,它工作正常
  • 你是right @SanderDeDycker,对不起。
  • @BrijRajKishore 我错了,抱歉,请查看我的更新答案。为您的问题 +1。
  • 你是对的。我将使用字符串。我认为这就是我在删除重复项之前变得奇怪的原因:51-thread-select 当我调试时
【解决方案3】:

这一行:

input[i] = '\0';

不做任何事情(input[i] 已经具有该值,因为那是循环的结束条件)。然后递归调用removeConsecutiveDuplicates 函数,但字符串的长度仍然相同,因此您将继续进行递归调用,直到发生堆栈溢出。

相反,您需要使字符串长度更小:

input[i - 1] = '\0';

避免这种无限递归。

【讨论】:

    猜你喜欢
    • 2016-01-12
    • 2010-12-20
    • 2016-08-23
    • 1970-01-01
    • 2018-01-16
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多