C中的递归问题

时间:2010-05-09 09:08:00

标签: c recursion

我一直试图解决这个问题几天,但似乎我还没有掌握递归的概念。

我必须在C中构建一个程序(递归是必须的,但也允许循环),它执行以下操作: 用户输入2个不同的字符串。例如: 字符串1 - ABC 字符串2 - DE

程序应该打印字符串,这些字符串由用户输入的字符串组合而成。 规则是每个字符串(1和2)中字母的内部顺序必须保留。 这是string1 = ABC&的输出。 string2 = DE“:

ABCDE abdce ABDEC adbce adbec adebc dabce dabec daebc DEABC

如果有人能帮助我,那就太好了。 谢谢你们。

4 个答案:

答案 0 :(得分:3)

这是Java中的部分解决方案:它应该具有指导性:

public class Join {                                       // prints:
   static void join(String s, String s1, String s2) {     // ABCde
      if (s1.isEmpty() || s2.isEmpty()) {                 // ABdCe
         System.out.println(s + s1 + s2);                 // ABdeC
      } else {                                            // AdBCe
         join(s + s1.charAt(0), s1.substring(1), s2);     // AdBeC
         join(s + s2.charAt(0), s1, s2.substring(1));     // AdeBC
      }                                                   // dABCe
   }                                                      // dABeC
   public static void main(String[] args) {               // dAeBC
      join("", "ABC", "de");                              // deABC
   }
}

如何运作

基本上你有String s,“输出流”和String s1, s2,即“输入流”。在每个机会,您首先从s1开始,然后再次尝试从s2开始,以递归方式探索这两个选项。

如果“输入流”在任何时候都是空的,那么你别无选择,只能留下任何剩余的东西(如果有的话)。

答案 1 :(得分:3)

这里是C语言,基于@polygenelubricants使用的相同想法。并不是我偷了他的想法,这是一个经典问题,这是最简单的方法:)。

#include <stdio.h>
#include <string.h>

void solve(const char *str1, const char *str2,
           const int length1, const int length2,
           char *output, int pozOut, int pozIn1, int pozIn2)
{
    if (pozIn1 == length1 && pozIn2 == length2)
    {
        printf("%s\n", output);
        return;
    }

    if (pozIn1 < length1)
    {
        output[pozOut] = str1[pozIn1];
        solve(str1, str2, length1, length2, output, pozOut + 1, pozIn1 + 1, pozIn2);
    }

    if (pozIn2 < length2)
    {
        output[pozOut] = str2[pozIn2];
        solve(str1, str2, length1, length2, output, pozOut + 1, pozIn1, pozIn2 + 1);
    }
}

int main()
{
    char temp[100]; // big enough to hold a solution.
    solve("ABC", "12", strlen("ABC"), strlen("12"), temp, 0, 0, 0);

    return 0;
}

这可以改进。例如,你如何摆脱一些参数?
此外,这有一个错误:您应该确保output在打印之前包含'\0',否则您可能会得到意外的结果。我会留给你修理。

答案 2 :(得分:2)

我不觉得我想写下整个算法。但是,这里有一些可能对您有帮助的线索。

基本上,您必须合并两个字符串,保持字符顺序。这就像你有两堆可能不同的尺寸。

在你的例子中:

stack #1: A B C
stack #2: D E

您还知道结果字符串的长度是两个输入字符串长度的总和。 (所以你知道要分配多长时间)

如果逐个字符继续:每转一圈,你可以选择从堆栈#1或堆栈#2中弹出一个字符,然后继续。 (这可能是递归)。如果你汇总所有可能的电话,你将获得所有结果字符串。

当我在大学时,我常常喜欢这样的问题:有时候看起来很难,但是当你自己解决它时,所以会有所回报!

如果您需要更多线索,请随时发表评论。

答案 3 :(得分:2)

与IVlad相同的算法,但动态分配结果数组,并使用指针而不是索引使我觉得它更清晰。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void solve(const char* result, const char* x0, const char* x1, char* p) {
    if (!*x0 && !*x1) printf("%s\n", result);
    if (*x0) {
        *p = *x0;
        solve(result, x0 + 1, x1, p + 1);
    } 
    if (*x1) {
        *p = *x1;
        solve(result, x0, x1 + 1, p + 1);
    }
}

int main(int argc, char* argv[]) {
    if (argc >= 3) {
        size_t total_length = strlen(argv[1]) + strlen(argv[2]) + 1;
        char *result = malloc(total_length);
        if (result) {
            result[total_length - 1] = '\0';
            solve(result, argv[1], argv[2], result);
            free(result);
        }
    }
    return 0;
}