当前位置: 首页 > 知识库问答 >
问题:

什么是最好的方法来设计递归函数,产生所有的N位数字的组合?

孔彭祖
2023-03-14

作为我大学算法课程的一部分,我们必须设计一个递归函数来生成所有n位数的组合。

112

113

121

221

222

223

322

323

331

void S6_1(int r, int n, int p, int d)
{
    if (d == 0)
        return;
    S6_1(r, n, p, d - 1);
    r = r * 10 + d;
    if (p == 1)
        cout << r << endl;
    else
        S6_1(r, n, p - 1, n);
}

void S6(int n)
{
    S6_1(0, n, n, n);
}

我非常感谢你能提供的任何帮助

共有1个答案

归泽宇
2023-03-14

归纳地思考:你如何把用[1..n]中的数字生成所有n位数的问题分解成一个较小的实例,再加上一点更多的工作?也许最明显的是将所有可能的数字加到递归生成的所有(n-1)位数字的前面。我将使用C(但C++类似)在缓冲区中一次累积一个数字。

// In buf[i..n-1], enumerate all numbers having n-i digits with values in [1..n]. 
void print_all(char *buf, int i, int n) {
  if (i == n) {               // Here n - i == 0, so we're done. Print.
    printf("%.*s\n", n, buf);
    return;
  }
  for (int digit = 1; digit <= n; ++digit) {
    buf[i] = digit + '0';     // put a digit at position i
    print_all(buf, i + 1, n); // recursively put the rest
  }
}

称之为:

char buf[n];
print_all(buf, 0, n);

int中构建数字也很好。代码略短,但它将int分解成字符串的工作留给了printf,因此从某种意义上说,这是双重工作:

void print_all(int b, int i, int n) {
  if (i == n) {
    printf("%d\n", b);
    return;
  }
  for (int digit = 1; digit <= n; ++digit) {
    print_all(10 * b + digit, i + 1, n);
  }
}
print_all(0, 0, n);

正如我在评论中指出的,用更难理解的递归代替明显的循环应用程序是不明智的。但既然你问了,

// Enumerate all numbers formed by appending to the number in b all (n-i)-digit
// numbers starting with a digit in [d..n] and all other digits in [1..n].
void print_all(int d, int b, int i, int n) {
  if (d > n) return;
  if (i == n) {
    printf("%d\n", b);
    return;
  }
  print_all(1, 10 * b + d, i + 1, n); // enumerate all with more digits
  print_all(d + 1, b, i, n); // enumerate other values of i'th digit
}

并呼吁:

print_all(1, 0, 0, n);
 类似资料:
  • 是否有一种方法可以编写递归函数,该函数打印数字中的位数,以便: -它是一个无效函数 -"if"条件是if(num==0),返回 -“else”将调用递归。 我看到了两种不同类型的代码,其中一种是“if”条件具有递归调用,另一种是用于“return”。但这不是我想要的。 我很不擅长递归,并试图通过自己编写代码来理解它,但没有成功。 这是我的代码(我明白为什么它打印122而不是3,但我真的不知道如何以

  • 问题内容: 在JavaScript中串联N个对象数组的最有效方法是什么? 数组是可变的,结果可以存储在输入数组之一中。 问题答案: 如果要连接两个以上的数组,那么这样做是为了方便和可能的性能。 对于仅连接两个数组,可以使用接受多个包含要添加到数组中的元素的参数的事实来代替将一个数组中的元素添加到另一个数组的末尾而不产生新数组。使用它也可以代替它,但是这样做似乎没有性能优势。 在ECMAScript

  • 问题内容: 质数的生成很简单,但是递归地找到它并生成(质数)的最快方法是什么? 这是我的解决方案。但是,这不是最佳方法。我认为是O(N * sqrt(N))。如果我错了,请纠正我。 问题答案: 对于递归,您应该使用 记忆 来改善递归功能,这意味着如果找到素数将其保存在数组中,并且在未调用isPrime(n,(int)Math.sqrt( n))。同样,如果isPrime(n,i)返回true,将其

  • 问题内容: 现在我在做 但是有更好的方法吗?类似于Scala的 问题答案: 我认为这样可以使操作更简洁,您不必处理减法和索引编制:

  • 现在我正在做 但是有没有更好的方法呢?类似于Scala的

  • 问题内容: 我有一个,我想将每个索引的值设置为相同的值。 有一种很明显的方法(迭代): 但是我想知道是否有一种可以利用的方法或某种等效方法可以绕过迭代的需要。有没有办法做到这一点? 编辑: 从 这是完全相同的过程,这表明可能没有更好的方法可以做到这一点。 +1对所有提出建议的人-你们都是正确的,谢谢。 问题答案: 试试:数组javadoc