ページ 11

nの順列の求め方

Posted: 2016年6月07日(火) 21:36
by books
C言語初心者です。
キーボードから数値を入力してその数の順列を求めて配列に入れる方法を教えてください。
例:
n = 3;
a[18]={0, 1, 2, 0, 2, 1, 1, 2, 0, 1, 0, 2, 2, 1, 0, 2, 0, 1};
このようにしたいです。

Re: nの順列の求め方

Posted: 2016年6月08日(水) 00:23
by box
キーボードから入力する数値によって配列aの要素数が動的に決まります。
よって、動的に領域を確保するmalloc()系の関数についての知識が必要でありましょう。

Re: nの順列の求め方

Posted: 2016年6月08日(水) 01:58
by みけCAT
入力は標準入力に限らず、キーボードからでないとダメですか?

Re: nの順列の求め方

Posted: 2016年6月08日(水) 05:56
by books
キーボードからの入力ではなくても、指定した数値の順列を配列に納められれば大丈夫です。

Re: nの順列の求め方

Posted: 2016年6月08日(水) 06:09
by かずま
n が大きくなると、配列 a の要素数は爆発的に増えるので、
n は 10 程度まででしょう。
それなら a は静的に確保してよいと思います。

あなたの使っている環境は何ですか?
Linux だったら、標準出力をファイルに切り替えて、行数を数えてみてください。

$ echo 10 | ./a.out >result
$ wc -l result

コード:

#include <stdio.h>

int a[1*2*3*4*5*6*7*8*9*10 * 10];  // 3628800 * 10

int perm(int *b, int *e)
{
    int *p, *q, *r, t;
    if (b + 1 >= e) return 0;
    for (p = e - 1; ; ) {
        r = p;
        if (*--p < *r) {
            for (q = e; *p >= *--q; ) ;
            t = *p, *p = *q, *q = t;
            while (r < --e) t = *e, *e = *r, *r++ = t;
            return 1;
        }
        if (p == b) {
            while (b < --e) t = *e, *e = *b, *b++ = t;
            return 0;
        }
    }
}

int main(void)
{
    int v[10], i, j, k, n;
    while (printf(">> "), scanf("%d", &n) == 1 && n > 0 && n <= 10) {
        for (i = 0; i < n; i++) v[i] = i;
        j = 0;
        do {
            for (i = 0; i < n; i++) a[j++] = v[i];
        } while (perm(v, v + n));
        for (k = 0; k < j; ) {
            for (i = 0; i < n; i++) printf(" %d", a[k++]);
            putchar('\n');
        }
    }
    return 0;
}