【问题标题】:Listing all permutations of digits without repeating in C language [duplicate]列出数字的所有排列而不用C语言重复[重复]
【发布时间】:2019-06-03 22:05:25
【问题描述】:

所以我有这个 C 语言的作业问题,我在过去 5 个小时里一直在研究,但不知道出了什么问题。

问题陈述:

取 n 作为从 1 到 9 的位数,并打印所有可能形成的不重复数字的数字。例如如果 n = 3,则数字为 1、2、3,数字为 123、132、231、213、321、312。

输入:2 输出:12、21

输入:3 输出:123、132、231、213、321、312

这是我目前所做的:

#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 10

void print(int *num, int n)
{
    int i;
    for ( i = 0 ; i < n ; i++){
        printf("%d", num[i]);
    }
    printf("\n");
}

int main()
{
    int num[N];
    int temp;
    int i, n, j,k;

    printf("\nNo of digits? : ");
    scanf("%d", &n);

    for(k=0; k<n; k++){
        num[k] = k + 1; 
    }

    for (j = 1; j <= n; j++) {
        for (i = 0; i < n-1; i++) {
            temp = num[i];
            num[i] = num[i+1];
            num[i+1] = temp;
            print(num, n);
        }
    }
    return 0;
}

我得到了最多 3 位数字的预期结果。 但是从 4 开始,它并没有显示所有的数字排列。

No of digits? : 4

2134
2314
2341
3241
3421
3412
4312
4132
4123
1423
1243
1234

设置计数器直到 n! 数组将超出索引。

那么如何正确计算所有排列呢?

【问题讨论】:

  • 您的程序没有创建您声明的输出。请永远不要通过排序等方式修改输出。而是向我们展示程序真正打印的内容。当然也向我们展示了错误的输出。不仅是正确的案例。
  • 回溯是一种方法,如果您对迭代解决方案感兴趣:geeksforgeeks.org/johnson-trotter-algorithm
  • 我不同意重复标记,这里的问题比较简单,“Print all permutation in lexicographic order”的解决方案比较复杂,不能针对当前问题进行

标签: c permutation


【解决方案1】:

我错过了什么?

订购 n 个元素的可能性数量是 factorial(n),您的两个叠瓦 for 无法为任何 n 值计算 factorial(n),因此他们无法找到所有订单。


一个可能的解决方案是:

#include <stdio.h>

/* current is the number under fabrication 
   max is the max number of digit and also the max digit to use
   n is the number of digits to add to current
   used[n] is 0 if the digit n is not yet used, else 1 */

void permut(unsigned current, unsigned max, unsigned n, int used[])
{
  if (n == 0)
    printf("%d\n", current);
  else {
    unsigned i;

    for (i = 1; i <= max; ++i) {
      if (!used[i]) {
        used[i] = 1;
        permut(current*10 + i, max, n - 1, used);
        used[i] = 0;
      }
    }
  }
}

int main()
{
  unsigned n;
  int used[10] = { 0 }; /* used[n] is 0 if the digit n is not yet used */

  printf("No of digits? : ");
  if ((scanf("%u", &n) != 1) || (n == 0) || (n > 9))
    return 0;

  permut(0, n, n, used);
  return 0;
}

2:

12
21

对于 3:

123
132
213
231
312
321

4:

1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321

【讨论】:

  • 忘了说我知道了。我会添加它。我的问题是如何纠正它?
  • @user101 我希望你能从我关于事实的评论中自己找到,反正我用提案编辑了我的答案
  • 你能解释一下permute函数吗?
  • @user101 我加了cmets来解释变量的作用,如果还是看不懂请在调试器下执行,算法很简单
猜你喜欢
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多