C で書いてみたので、これが理解できたら、C++ に書き直してみてください。
C
1#include <stdio.h> // printf, putchar
2#include <stdlib.h> // rand
3
4#define N 6
5
6int a[N], p[N];
7
8void divide(int n)
9{
10 for (int m = 1; ; m++) {
11 p[n] = p[n-1] + m;
12 if (p[n] < N) divide(n+1);
13 else {
14 for (int i = 0; i < n; i++) {
15 int j = p[i], k = p[i+1];
16 printf(" {%d", a[j]);
17 while (++j < k) printf(",%d", a[j]);
18 putchar('}');
19 }
20 putchar('\n');
21 return;
22 }
23 }
24}
25
26int main(void)
27{
28 for (int i = 0; i < N; i++) a[i] = i + 1;
29 for (int i = 0; i < N; i++) {
30 int r = rand() % N;
31 int t = a[r]; a[r] = a[i]; a[i] = t;
32 }
33 divide(1);
34}
N が 6 の場合の実行結果
text
1 {2} {1} {4} {5} {6} {3}
2 {2} {1} {4} {5} {6,3}
3 {2} {1} {4} {5,6} {3}
4 {2} {1} {4} {5,6,3}
5 {2} {1} {4,5} {6} {3}
6 {2} {1} {4,5} {6,3}
7 {2} {1} {4,5,6} {3}
8 {2} {1} {4,5,6,3}
9 {2} {1,4} {5} {6} {3}
10 {2} {1,4} {5} {6,3}
11 {2} {1,4} {5,6} {3}
12 {2} {1,4} {5,6,3}
13 {2} {1,4,5} {6} {3}
14 {2} {1,4,5} {6,3}
15 {2} {1,4,5,6} {3}
16 {2} {1,4,5,6,3}
17 {2,1} {4} {5} {6} {3}
18 {2,1} {4} {5} {6,3}
19 {2,1} {4} {5,6} {3}
20 {2,1} {4} {5,6,3}
21 {2,1} {4,5} {6} {3}
22 {2,1} {4,5} {6,3}
23 {2,1} {4,5,6} {3}
24 {2,1} {4,5,6,3}
25 {2,1,4} {5} {6} {3}
26 {2,1,4} {5} {6,3}
27 {2,1,4} {5,6} {3}
28 {2,1,4} {5,6,3}
29 {2,1,4,5} {6} {3}
30 {2,1,4,5} {6,3}
31 {2,1,4,5,6} {3}
32 {2,1,4,5,6,3}
追記
何分割するかで分類してみました。
C
1#include <stdio.h> // printf, putchar
2#include <stdlib.h> // rand
3
4#define N 6
5
6int a[N], p[N];
7
8void divide(int n)
9{
10 if (n == 1) {
11 for (int i = 0; ; i++) {
12 int j = p[i], k = p[i+1];
13 printf(" {%d", a[j]);
14 while (++j < k) printf(",%d", a[j]);
15 putchar('}');
16 if (j == N) break;
17 }
18 putchar('\n');
19 return;
20 }
21 for (int m = 1; ; m++) {
22 p[n-1] = p[n] - m;
23 if (p[n-1] <= 0) break;
24 divide(n-1);
25 }
26}
27
28int main(void)
29{
30 for (int i = 0; i < N; i++) a[i] = i + 1;
31 for (int i = 0; i < N; i++) {
32 int r = rand() % N;
33 int t = a[r]; a[r] = a[i]; a[i] = t;
34 }
35 for (int i = 1; i <= N; i++) {
36 printf("--- %d ---\n", i);
37 p[i] = N;
38 divide(i);
39 }
40}
text
1--- 1 ---
2 {2,1,4,5,6,3}
3--- 2 ---
4 {2,1,4,5,6} {3}
5 {2,1,4,5} {6,3}
6 {2,1,4} {5,6,3}
7 {2,1} {4,5,6,3}
8 {2} {1,4,5,6,3}
9--- 3 ---
10 {2,1,4,5} {6} {3}
11 {2,1,4} {5,6} {3}
12 {2,1} {4,5,6} {3}
13 {2} {1,4,5,6} {3}
14 {2,1,4} {5} {6,3}
15 {2,1} {4,5} {6,3}
16 {2} {1,4,5} {6,3}
17 {2,1} {4} {5,6,3}
18 {2} {1,4} {5,6,3}
19 {2} {1} {4,5,6,3}
20--- 4 ---
21 {2,1,4} {5} {6} {3}
22 {2,1} {4,5} {6} {3}
23 {2} {1,4,5} {6} {3}
24 {2,1} {4} {5,6} {3}
25 {2} {1,4} {5,6} {3}
26 {2} {1} {4,5,6} {3}
27 {2,1} {4} {5} {6,3}
28 {2} {1,4} {5} {6,3}
29 {2} {1} {4,5} {6,3}
30 {2} {1} {4} {5,6,3}
31--- 5 ---
32 {2,1} {4} {5} {6} {3}
33 {2} {1,4} {5} {6} {3}
34 {2} {1} {4,5} {6} {3}
35 {2} {1} {4} {5,6} {3}
36 {2} {1} {4} {5} {6,3}
37--- 6 ---
38 {2} {1} {4} {5} {6} {3}
追記2
分割の全パターンを表示するのではなく、
指定した分割数で 1つだけ表示するようにしてみました。
C
1#include <stdio.h> // printf, putchar
2#include <stdlib.h> // rand
3
4#define N 12
5
6void print(const int a[], int i, int j)
7{
8 printf(" {%d", a[i]);
9 while (++i < j) printf(",%d", a[i]);
10 putchar('}');
11}
12
13void divide(const int a[], int n)
14{
15 int i = 0;
16 for (int k; --n > 0; i += k) {
17 k = rand() % (N - i - n) + 1;
18 print(a, i, i + k);
19 }
20 print(a, i, N);
21 putchar('\n');
22}
23
24int main(void)
25{
26 int a[N];
27 for (int i = 0; i < N; i++) a[i] = i + 1;
28 divide(a, 3);
29 divide(a, 2);
30}
配列をグローバル変数ではなく、関数の引数にしました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/29 02:48
2020/11/29 06:26