C中的递归问题

发布于 2024-08-31 20:06:37 字数 325 浏览 1 评论 0原文

我已经尝试解决这个问题几天了,但似乎我还没有掌握递归的概念。

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

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

abcde abdce abdec 阿德布塞 阿德贝克 阿德贝克 达布采 达贝克 达埃布克 deabc

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

I've been trying to solve this problem for a few days now but it seems I haven't grasped the concept of recursion,yet.

I have to build a program in C (recursion is a must here but loops are allowed as well) which does the following:
The user inputs 2 different strings.For example:
String 1 - ABC
String 2 - DE

The program is supposed to print strings which are combined of the ones the user has entered.
the rule is that the inner order of the letters in each string (1&2) must remain.
That's the output for string1=ABC & string2=DE ":

abcde
abdce
abdec
adbce
adbec
adebc
dabce
dabec
daebc
deabc

If anyone could give me a hand here, it would be great.
Thanks guys.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

失退 2024-09-07 20:06:37

这是 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 获取,递归地探索这两个选项。

如果任何时候任一“输入流”为空,那么您别无选择,只能采用剩下的内容(如果有)。

Here is a partial solution in Java: it should be instructive:

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

How it works

Basically you have String s, the "output stream", and String s1, s2, the "input stream". At every opportunity, you first take from s1, and later you try again and take from s2, exploring both options recursively.

If at any time either "input stream" is empty, then you're left with no other choice but take whatever's left (if any).

人间不值得 2024-09-07 20:06:37

这里是用 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',否则您可能会得到意外的结果。我会把这个问题留给你来解决。

Here it is in C, based on the same idea @polygenelubricants used. It's not that I stole his idea, it's that this is a classical problem and this is the simplest approach :).

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

This can be improved. For example, how would you get rid of some of the parameters?
Also, this has a bug: you should make sure that output contains a '\0' at the end before printing it, otherwise you might get unexpected results. I'll leave that for you to fix.

柠檬色的秋千 2024-09-07 20:06:37

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

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

在您的示例中:

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

您还知道生成的字符串的长度为两个输入字符串的长度之和。 (所以你已经知道要分配多少长度)

如果你逐个字符地进行:每一回合你都可以选择是从堆栈 #1 还是堆栈 #2 中弹出一个字符,然后继续。 (这里可能是递归)。如果您汇总所有可能的调用,您将获得所有结果字符串。

我在大学时曾经喜欢这样的问题:有时看起来很困难,但是当你自己解决它时如此值得!

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

I don't feel like I want to write down the whole algorithm. However, here are some leads that might help you.

Basically, you must merge two strings, keeping the characters order. It's like you have 2 stacks of possibly different sizes.

In your example:

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

You also know that the resulting string will have as length the sum of the length of the two input strings. (So you know already how much length to allocate)

If you proceed character by character: each turn you can choose wether to pop one character from either the stack #1 or the stack #2, then continue. (Here could be the recursion). If you roll up all the possible calls you'll have all the resulting strings.

I use to like problems like that when I was in college: it can seem difficult sometimes, but it is so rewarding when you solve it by yourself !

Feel free to comment if you need more clues.

百合的盛世恋 2024-09-07 20:06:37

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

The same algorithm as IVlad, but dynamically allocating the result array, and using pointers rather than indexes making it a bit clearer I think.

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文