合計 昨日 今日

配列内[5][15]の組み合わせ.

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月21日(火) 17:10
No: 1
(OFFLINE)

 配列内[5][15]の組み合わせ.

1~10の数字を使い、被らない[5][20]の配列で6個のデータ配列を作り出し、その6個の配列から5個のデータ配列を取り出して表示する組み合わせを全て表示させる。というものを作ろうと思うのですが、どのように組めばよいのか分かりません。
どなたかご教授願います。

説明が下手なので作りたいものの例を載せます。

12345678910//////////
///12345678910///////
//////////12345678910
//////12345678910////
/////////12345678910/

////12345678910//////
////////12345678910//
//////////12345678910
12345678910//////////
///////12345678910///

//12345678910////////
////12345678910//////
//////////12345678910
/////12345678910/////
12345678910//////////

////////12345678910//
/12345678910/////////
//////////12345678910
////12345678910//////
//////12345678910////

///12345678910///////
12345678910//////////
//////////12345678910
//12345678910////////
/////12345678910/////

/12345678910/////////
//12345678910////////
//////////12345678910
////////12345678910//
///12345678910///////


このように6個のデータ配列を作りだし、1~5の配列、2~6の配列、3~1の配列…と
6通りを表示させる全ての組み合わせを表示させるプログラムを作りたいです。
その中の条件として
[5][20]の6個のデータ配列の数字のスタート位置が例のように被らないようにしたいです。
[3][20]の配列は例のように、必ず11番目からの開始にしたいです。

この条件で一つのデータ配列につき6通りの組み合わせを表示させ、
全ての組み合わせを表示させるプログラムを作りたいです。
どうかよろしくお願いします。

Name: よもやま
[URL]
ぴよぴよ(292 ポイント)
Date: 2017年11月22日(水) 00:05
No: 2
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

似た内容のトピックがありますが、同じではないのでしょうか。
No 19736

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月22日(水) 02:26
No: 3
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

似ていますが自分の得たいものではないと思うので違うものかと…

そのトピックでは
////////////12345678
90///////////1234567

というように9が先頭データに入っているのですが私の得たい値は
/////12345678910
12345678910/////

と必ず1からのスタートで90///////////1234567のような
結果ではありません。

言い訳のようですみませんがよろしくお願いします。

Name: かずま
[URL]
Date: 2017年11月22日(水) 03:27
No: 4
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

のんのん#24 さんが書きました:1~10の数字を使い、被らない[5][20]の配列で6個のデータ配列を作り出し、その6個の配列から5個のデータ配列を取り出して表示する組み合わせを全て表示させる。というものを作ろうと思うのですが、

「1~10の数字を使い」
1~9 は数字ですが、
10 は、数または数値です。
10 は、1 と 0 という 2つの数字の並びです。
そうすると、これは文字列です。

「1~10の数を使い」と言いたいのですか?
それとも「0~9 の数字を使い」ですか?

「被らない[5][20]の配列で」
タイトルで「配列内[5][15]の組み合わせ.」
となっていますが、[15] は [20]の間違いですか?
あとで出てくる [3][20] の配列も意味不明です。

それから、何の配列ですか?
 数値なら int の配列。 1, 2, ..., 10
 文字なら char の配列。 '1', '2', ..., '10', '/'
 文字列なら char * の配列。 "1", "2", ..., "10", "/"
どれかわからないとプログラムは書けません。
10 が数値なら int の配列に入りますが、
char の配列には、'10' は入りません。
また、int の配列だとすると、
表示例にある / は何ですか?
これは数値ではありません。

表示の先頭「12345678910//////////」
これは、11個の数字と 10個の / ですなので、
21文字になっていますが、これでいいのですか?

これは何かの課題なのですか?
それなら、その課題の文章を一字一句変えずに
そのままコピペしてください。

Name: usao
[URL]
ハッカー(140,412 ポイント)
Date: 2017年11月22日(水) 10:10
No: 5
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

内容は少なくとも以下の2つの部分に分かれていそうですが,実際のところどこらへんが問題なのか,焦点を絞ることはできないのでしょうか.

(1)
> 1~10の数字を使い、被らない[5][20]の配列で6個のデータ配列を作り出し

言葉の意味がよくわかりませんが,このデータ生成部分はできているのでしょうか.
この部分が問題なのであれば,
(既に指摘されているように)内容がわかるようなまともな説明が必要でしょう.

(2)
> その6個の配列から5個のデータ配列を取り出して表示する組み合わせを全て表示させる

「6個のデータ{A,B,C,D,E,F}が存在するときに,そこから5個のデータを選び出すパターン を全て列挙する」
ことは問題無くできるのでしょうか.
(仮にこの部分だけが問題なのだとしたら,(1)の「配列がどうの」という話とは無関係にこの列挙方法の話だけをすればよい)

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月22日(水) 10:48
No: 6
(OFFLINE)

 Re: 配列内[5][20]の組み合わせ.

「1~10の数を使い」と言いたいのですか?
それとも「0~9 の数字を使い」ですか?

→"10"は文字列になるんですね。初めて知りました。
「1~10の数を使い」です。

「被らない[5][20]の配列で」
タイトルで「配列内[5][15]の組み合わせ.」
となっていますが、[15] は [20]の間違いですか?
あとで出てくる [3][20] の配列も意味不明です。

→タイトルは間違い、です。訂正します。
 [3][20]というのは[5][20]の配列の三行目は常に11番目から文字列が
始まる、という意味です。

表示の先頭「12345678910//////////」
これは、11個の数字と 10個の / ですなので、
21文字になっていますが、これでいいのですか?

→/は空白の意味です。すいません。
"10"が一文字でなく二文字ということであれば21文字で間違いないです。

これは何かの課題なのですか?
それなら、その課題の文章を一字一句変えずに
そのままコピペしてください。

→課題ではなく、こういうものを作りたいっていう
考えなので元の文章はありません。
説明が下手ですみません。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月22日(水) 10:55
No: 7
(OFFLINE)

 Re: 配列内[5][20]の組み合わせ.

usao さんが書きました:内容は少なくとも以下の2つの部分に分かれていそうですが,実際のところどこらへんが問題なのか,焦点を絞ることはできないのでしょうか.

(1)
> 1~10の数字を使い、被らない[5][20]の配列で6個のデータ配列を作り出し

言葉の意味がよくわかりませんが,このデータ生成部分はできているのでしょうか.
この部分が問題なのであれば,
(既に指摘されているように)内容がわかるようなまともな説明が必要でしょう.

(2)
> その6個の配列から5個のデータ配列を取り出して表示する組み合わせを全て表示させる

「6個のデータ{A,B,C,D,E,F}が存在するときに,そこから5個のデータを選び出すパターン を全て列挙する」
ことは問題無くできるのでしょうか.
(仮にこの部分だけが問題なのだとしたら,(1)の「配列がどうの」という話とは無関係にこの列挙方法の話だけをすればよい)



(1)データ生成部分は自動で生成されてほしいです。

(2)6個のデータが生成されると、そこから、6通りの5個のパターンを表示させたいです。

Name: usao
[URL]
ハッカー(140,412 ポイント)
Date: 2017年11月22日(水) 12:04
No: 8
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

【その話の中で,できている部分はどこなのか? どこがわからない点なのか?】 といった事柄を問うているのですが…
ご自身の取り組んだ結果等を提示することはできないのでしょうか.

具体的な質問は一体何なのか?

「やりたいことを何か思いついたけど,自分自身では{やらない?,やれない?,やりたくない?}から,誰かプログラミングよろしく」
みたいな話に見えてしまいますが,そういう話ですか?

#指摘されている類似トピックはあなたの立てたものなのでしょうか?
 それとも別人ですか?

Name: かずま
[URL]
Date: 2017年11月22日(水) 15:51
No: 9
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:それから、何の配列ですか?
 数値なら int の配列。 1, 2, ..., 10
 文字なら char の配列。 '1', '2', ..., '10', '/'
 文字列なら char * の配列。 "1", "2", ..., "10", "/"
どれかわからないとプログラムは書けません。
10 が数値なら int の配列に入りますが、
char の配列には、'10' は入りません。
また、int の配列だとすると、
表示例にある / は何ですか?
これは数値ではありません。

この質問に答えてもらっていないので
プログラムが書けません。
/ が空白だとしても、それは int ではありません。
0 を入れて、表示を空白にするということでしょうか?

また、「被らない」の意味をもっと詳しく説明してください。

例えば、次のようなデータを作ったら、
2行目と 5行目が同じなのでダメという意味でしょうか?
12345678910//////////
///12345678910///////
//////////12345678910
//////12345678910////
///12345678910///////

あるいは、次のように 6個のデータのうち
2個が同じだったらダメという意味でしょうか?

12345678910//////////
///12345678910///////
//////////12345678910
//////12345678910////
/////////12345678910/

12345678910//////////
///12345678910///////
//////////12345678910
//////12345678910////
/////////12345678910/

のんのん#24 さんが書きました:そのトピックでは
////////////12345678
90///////////1234567

というように9が先頭データに入っているのですが私の得たい値は
/////12345678910
12345678910/////

と必ず1からのスタートで90///////////1234567のような
結果ではありません。

一行が 21文字で "012345678910" という 11文字の
前に n個 (0≦n≦10)、後ろに (10-n) 個の空白がある
ものを 1, 2, 4, 5行目に置くということでしょうか?
n の個数は乱数で決めるのでしょうか?

Name: Dixq (管理人)
(管理人)
[URL]
ウィザード(1,489,942 ポイント)
Date: 2017年11月23日(木) 11:01
No: 10
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

>> 似た内容のトピックがありますが、同じではないのでしょうか。
>> No 19736

> 似ていますが自分の得たいものではないと思うので違うものかと…

何故ウソを言われるのでしょうか?
サイト管理者(私含めて5名)はアクセス元の情報が分かるのでウソを書かないて下さい。
せっかく時間かけてソースコードまで書いたのに返信もなく「別の人の物だ」と言われると回答者としては悲しいです。
私の予測が違っていたなら元のトピックで補足して頂きたかった。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月23日(木) 16:56
No: 11
(OFFLINE)

 Re: 配列内[5][20]の組み合わせ.

usao さんが書きました:【その話の中で,できている部分はどこなのか? どこがわからない点なのか?】 といった事柄を問うているのですが…
ご自身の取り組んだ結果等を提示することはできないのでしょうか.

具体的な質問は一体何なのか?

「やりたいことを何か思いついたけど,自分自身では{やらない?,やれない?,やりたくない?}から,誰かプログラミングよろしく」
みたいな話に見えてしまいますが,そういう話ですか?

#指摘されている類似トピックはあなたの立てたものなのでしょうか?
 それとも別人ですか?

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int main(void)
{
  int k=0,i=0,j=0,L=0,r=0; //文字の初期化    
  printf("k=");                                  //情報ブロックk の入力
  scanf("%d", &k);
  printf("L=");
  scanf("%d", &L);                              //情報ブロックの符号長L の入力
  printf("r=");                                 //オーバーヘッド数r の入力
  scanf("%d", &r);
 
                                   
  int y[k][L+r];
 
  for(i=0;i<k;i++){
    for(j=0;j<L+r;j++){
      printf("y[%d][%d]=",i+1,j+1); //符号ブロック の配列入力
      scanf("%d", &y[i][j]);
    }
  }
 
 
  //確認
 
    printf("y[%d][%d] = ",k,L+r);           //y
    for(i=0;i<k;i++){
      for(j=0;j<L+r;j++){
    printf("%d ", y[i][j]);
      }
      if(i!=k-1){
    printf("\n          ");
      }
      else{
      printf("\n");
      }
 
   return 0;
}


現段階はこのような感じです。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月23日(木) 17:06
No: 12
(OFFLINE)

 Re: 配列内[5][20]の組み合わせ.

それから、何の配列ですか?
 数値なら int の配列。 1, 2, ..., 10
 文字なら char の配列。 '1', '2', ..., '10', '/'
 文字列なら char * の配列。 "1", "2", ..., "10", "/"
どれかわからないとプログラムは書けません。
10 が数値なら int の配列に入りますが、
char の配列には、'10' は入りません。
また、int の配列だとすると、
表示例にある / は何ですか?
これは数値ではありません。
この質問に答えてもらっていないので
プログラムが書けません。
/ が空白だとしても、それは int ではありません。
0 を入れて、表示を空白にするということでしょうか?

→/の部分は0でも何もなしでも構いません.
10は数値のつもりでかいています.

また、「被らない」の意味をもっと詳しく説明してください。

例えば、次のようなデータを作ったら、
2行目と 5行目が同じなのでダメという意味でしょうか?
12345678910//////////
///12345678910///////
//////////12345678910
//////12345678910////
///12345678910///////

→こちらであってます!

一行が 21文字で "012345678910" という 11文字の
前に n個 (0≦n≦10)、後ろに (10-n) 個の空白がある
ものを 1, 2, 4, 5行目に置くということでしょうか?
n の個数は乱数で決めるのでしょうか?

→そういうことであってるはずです
nは乱数であっても初期設定でも構いません

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月23日(木) 17:09
No: 13
(OFFLINE)

 Re: 配列内[5][20]の組み合わせ.

Dixq (管理人) さんが書きました:>> 似た内容のトピックがありますが、同じではないのでしょうか。
>> No 19736

> 似ていますが自分の得たいものではないと思うので違うものかと…

何故ウソを言われるのでしょうか?
サイト管理者(私含めて5名)はアクセス元の情報が分かるのでウソを書かないて下さい。
せっかく時間かけてソースコードまで書いたのに返信もなく「別の人の物だ」と言われると回答者としては悲しいです。
私の予測が違っていたなら元のトピックで補足して頂きたかった。


申し訳ございません。学内の共用PCを貸し合い、これを3人で考えてるため似た質問をしていたみたいです。
本当にごめんなさい。

Name: Dixq (管理人)
(管理人)
[URL]
ウィザード(1,489,942 ポイント)
Date: 2017年11月24日(金) 00:40
No: 14
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

疑問は他にもありますが、一旦分かりましたので回答を続けます。

しかし、他の人もいっているように質問内容の仕様が明確でないので、明確に回答できない部分が多いです。
やりたいことを想像で作ってみました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
 
const static int NUM = 5;
const static int LEN = 21+1;
 
//引数の配列の中身をn個右にずらす
void displace(char arr[LEN], int n) {
    for (int j = 0; j < n; j++) {//n回処理
        int tmp = arr[LEN - 2];//最後の文字を一時保存
        for (int i = LEN - 2; i > 0; i--) {//1つずつずらす
            arr[i] = arr[i - 1];
        }
        arr[0] = tmp;//先頭に最後尾の文字をコピー
    }
}
 
//引数の配列の中に"12345678910          "をすべて格納する
void initialize(char arr[NUM][LEN]) {
    for (int i = 0; i < NUM; i++) {
        memcpy(arr[i], "12345678910//////////", LEN);
    }
}
 
//配列の中身を全て表示する
void show(char arr[NUM][LEN]) {
    for (int i = 0; i < NUM; i++) {
        printf("%s\n", arr[i]);
    }
    printf("\n");
}
 
//引数の2つを交換する
void swap(char &a, char &b) {
    char tmp = a;
    a = b;
    b = tmp;
}
 
//10個の配列要素をシャッフルする
void shuffle(char arr[10]) {
    for (int i = 0; i < 10; i++) {
        int pos = rand() % 10;//0~9の乱数を作る
        if (i == pos) {//生成した乱数がiと同じならもう一度
            i--;
            continue;
        }
        swap(arr[pos], arr[i]);//2つの数を交換
    }
}
 
//0~9の被らない乱数を5つ作って返す
void getRand(char ran[5]) {
    char arr[10] = {0,1,2,3,4,5,6,7,8,9};
    shuffle(arr);//arrの内容をシャッフル
    memcpy(ran, arr, 5);//先頭の5つをコピーして返す
}
 
int main() {
    srand((unsigned)time(NULL));//乱数が毎回変わるように現在の時間でシード
 
    char ran[6][5];//6つ分の5つの乱数
    for (int i = 0; i < 6; i++) {
        getRand(ran[i]);//5つの乱数を取得
        bool isSame = false;
        for (int j = 0; j < i; j++) {//今までの乱数と同じだったら
            if (memcmp(ran[i], ran[j], 5) == 0) {
                isSame = true;
            }
        }
        if (isSame) {//作り直し
            i--;
            continue;
        }
    }
 
    char arr[NUM][LEN];
    for (int i = 0; i < 6; i++) {
        initialize(arr);//初期状態の文字列を格納
        for (int j = 0; j < 5; j++) {
            if (j == 2) {//2番目の時だけ10個ずらす
                displace(arr[j], 10);
            }
            else {//それ以外の時は乱数分だけずらす
                displace(arr[j], ran[i][j]);
            }
        }
        show(arr);
    }
}


数値を代入しているという割には文字を代入しているようにも

実行結果
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
////////12345678910//
//12345678910////////
//////////12345678910
//////12345678910////
////12345678910//////
 
//12345678910////////
/////////12345678910/
//////////12345678910
/////12345678910/////
///////12345678910///
 
//12345678910////////
///12345678910///////
//////////12345678910
///////12345678910///
/////////12345678910/
 
/////12345678910/////
/12345678910/////////
//////////12345678910
//////12345678910////
///12345678910///////
 
/12345678910/////////
/////12345678910/////
//////////12345678910
12345678910//////////
//12345678910////////
 
///12345678910///////
/12345678910/////////
//////////12345678910
//12345678910////////
///////12345678910///


よくわからないのは

> この条件で一つのデータ配列につき6通りの組み合わせを表示させ、
> 全ての組み合わせを表示させるプログラムを作りたいです。

この点で6つではすべての組み合わせの表示にはなりません。
被らない6通りの表示をするということでいいのでしょうか?

しかしもっと何がやりたいからこの仕様になっているかという説明は求められないのでしょうか?
何がしたいからこんな質問に至っているのかが分かれば別のアプローチもあるかと思いますし、
質問内容が分からなくても回答者が理解できるかもしれません。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月24日(金) 11:51
No: 15
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

ありがとうございます。私自身もやりたいことが明確でなくて"こういうもの"をっていう段階なので。
説明が下手で申し訳ございませんが

////////12345678910//
//12345678910////////
//////////12345678910
//////12345678910////
////12345678910//////

と1つの配列を用意したら2進数のように/の部分は"何もないもの"=0とし、
数字(1~10)の表示されている場所は1という結果による視認か
0と1という区別がプログラムで組めるのであればそうしたいと考えています。

生成されたデータ配列を最初に6個表示し、その中から(1~5)、(2~6)、(3~1)…と5個を選び表示する
それが6個あるので、6通り表示させたいということです。

    [5][20]
   ※※11※※
   ※※11※※
   ※※11※※
6個{ ※※11※※
   ※※11※※
   ※※11※※

※=1~11 (数字は1~10なので11番目からまでしか表示できない)
全ての組み合わせを表示させる、というのは※にあたる数だけの組み合わせがあるので
それを表示させたいということです。

しかし、それでは11の24乗通りもあるので
1 2 11 3 4
3 5 11 10 8
4 7 11 8 11
5 9 11 2 7
2 8 11 4 10

というように縦と横(3列目は11で決めているので隣に11が入っていても問題ないものとする)
が被らないものというものにしたいのです。(その分の組み合わせの数が減るので)

最終的にはこれをファイル出力して、どのような組みあわせがあるかをみてその後に活用していこう
という話になっています。

わかりにくくて申し訳ございません。

Name: Dixq (管理人)
(管理人)
[URL]
ウィザード(1,489,942 ポイント)
Date: 2017年11月24日(金) 18:42
No: 16
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

私の頭が悪いのかやりたいことが全然分かりません…

まず私の提示したコードは間違ってるのでしょうか?

して、これは何をするために算出するんですか?

Name: かずま
[URL]
Date: 2017年11月27日(月) 01:30
No: 17
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

私の理解を書きますね。

////////12345678910//
//12345678910////////
//////////12345678910
//////12345678910////
////12345678910//////

この 1つのデータは 21桁 5行で構成されます。
1行は 12345678910 という 11文字の前後に
0個以上の / があります。
左右合わせて 10文字です。
1234567890 の文字列が何桁目から始まるか
というと、9, 3, 11, 7, 5 となっています。
3行目は必ず 11桁目から始まります。
他の行は 1~11桁目から始まり、
同じ桁のものがあってはなりません。
ただし、3行目と同じものはあってもよい。

5行のデータが (9 3 11 7 5) と表せました。
このようなものを 6個作ります。

[1] (9 3 11 7 5)
[2] (1 2 11 3 4)
[3] (3 5 11 10 8)
[4] (4 7 11 8 11)
[5] (5 9 11 2 7)
[6] (2 8 11 4 10)

横方向の 9 3 7 5 がすべて異なること。
縦方向の 9 1 3 4 5 2 がすべて異なること。
他の横縦も同様。そういう 6個を作ります。

そして、次のように 5個ずつを
ひとまとめにして 6通りの出力をする。

[1][2][3][4][5] を出力
[2][3][4][5][6] を出力
[3][4][5][6][1] を出力
[4][5][6][1][2] を出力
[5][6][1][2][3] を出力
[6][1][2][3][4] を出力

最後の出力は機械的なことなので、考えなくてよい。

問題は、[1]~[6] のデータが何通りできるか
ということではないのですか?

Name: かずま
[URL]
Date: 2017年11月27日(月) 01:33
No: 18
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:1行は 12345678910 という 11文字の前後に
0個以上の / があります。
左右合わせて 10文字です。

すみません。用語の不整合です。
「前後」と「左右」はどちらかに統一してください。

Name: かずま
[URL]
Date: 2017年11月27日(月) 02:33
No: 19
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

Offtopic :
Dixq (管理人) さんが書きました:
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
//引数の配列の中身をn個右にずらす
void displace(char arr[LEN], int n) {
    for (int j = 0; j < n; j++) {//n回処理
        int tmp = arr[LEN - 2];//最後の文字を一時保存
        for (int i = LEN - 2; i > 0; i--) {//1つずつずらす
            arr[i] = arr[i - 1];
        }
        arr[0] = tmp;//先頭に最後尾の文字をコピー
    }
}

一文字ずつずらすのを n 回繰り返すのは効率が悪そうです。
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
 
#define LEN (21 + 1)
 
//引数の配列の中身をn個右にずらす
void displace(char arr[LEN], int n) {
    for (int j = 0; j < n; j++) {//n回処理
        int tmp = arr[LEN - 2];//最後の文字を一時保存
        for (int i = LEN - 2; i > 0; i--) {//1つずつずらす
            arr[i] = arr[i - 1];
        }
        arr[0] = tmp;//先頭に最後尾の文字をコピー
    }
}                     // コピー回数は LEN * n
 
void displace2(char *arr, int n)
{
    char tmp[LEN - 1];  // 最後の '\0' は不要
    memcpy(tmp, arr + LEN - 1 - n, n); // arr の後半 n文字を tmp にコピー
    memcpy(tmp + n, arr, LEN - 1 - n); // arr の前半を tmp の続きにコピー
    memcpy(arr, tmp, LEN - 1);         // tmp 全体を arr にコピー
}                     // コピー回数は (LEN-1) * 2
 
void displace3(char *arr, int n)
{                      // n は LEN の半分以下なので、コピーの回数を減らせる
    char tmp[LEN / 2];
    memcpy(tmp, arr + LEN - 1 - n, n);  // arr の後半 n文字を tmp にコピー
    memmove(arr + n, arr, LEN - 1 - n); // arr の前半を後ろにずらす
    memcpy(arr, tmp, n);                // tmp の n文字を arr の先頭にコピー
}                     // コピー回数は (LEN-1) + n
 
void reverse(char *a, char *b)
{
    char t;
    while (a < --b) t = *a, *a++ = *b, *b = t;
}
 
void displace4(char *arr, int n)
{
    reverse(arr, arr + LEN - 1);     // arr 全体を逆順に
    reverse(arr, arr + n);           // arr の前半 n文字を逆順に
    reverse(arr + n, arr + LEN - 1); // arr の後半を逆順に
}                     // コピー回数は (LEN-1) * 6 だが、一時領域が不要
 
int main(void)
{
    char s[] = "12345678910//////////";
    puts(s);
    displace(s, 3); puts(s);
    displace2(s, 3); puts(s);
    displace3(s, 3); puts(s);
    displace4(s, 3); puts(s);
}

実行結果
コード[Text]: 全て選択
1
2
3
4
5
12345678910//////////
///12345678910///////
//////12345678910////
/////////12345678910/
10//////////123456789

Name: かずま
[URL]
Date: 2017年11月27日(月) 03:07
No: 20
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:5行のデータが (9 3 11 7 5) と表せました。

表示を数の並びで表せましたが、その逆は簡単です。
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
void print(const int *a)
{
    for (int i = 0; i < 5; i++)
        printf("%.21s\n", "//////////12345678910//////////" + 11 - a[i]);
}
 
int main(void)
{
    int a[5] = { 9, 3, 11, 7, 5 };
    print(a);
}

実行結果
コード[Text]: 全て選択
1
2
3
4
5
////////12345678910//
//12345678910////////
//////////12345678910
//////12345678910////
////12345678910//////

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月27日(月) 12:13
No: 21
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

Dixq (管理人) さんが書きました:私の頭が悪いのかやりたいことが全然分かりません…

まず私の提示したコードは間違ってるのでしょうか?

して、これは何をするために算出するんですか?



返事が遅れてしまいました。すいません。

見た感じあっています。ありがとうございます。

1通りしか生成されないので、これを全ての組み合わせを生成させることは出来るのでしょうか?

後はここから、かずまさんが言われているように6個のデータを表示させたら、そこから
1~5、2~6、3~1、4~2、5~3、6~4の6個を表示させたいです。

データをファイル出力させて、似たような組み合わせがあるかを判断したり、得られた結果から新たなものが発見
出来れば、と考えています。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月27日(月) 12:17
No: 22
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:私の理解を書きますね。

////////12345678910//
//12345678910////////
//////////12345678910
//////12345678910////
////12345678910//////

この 1つのデータは 21桁 5行で構成されます。
1行は 12345678910 という 11文字の前後に
0個以上の / があります。
左右合わせて 10文字です。
1234567890 の文字列が何桁目から始まるか
というと、9, 3, 11, 7, 5 となっています。
3行目は必ず 11桁目から始まります。
他の行は 1~11桁目から始まり、
同じ桁のものがあってはなりません。
ただし、3行目と同じものはあってもよい。

5行のデータが (9 3 11 7 5) と表せました。
このようなものを 6個作ります。

[1] (9 3 11 7 5)
[2] (1 2 11 3 4)
[3] (3 5 11 10 8)
[4] (4 7 11 8 11)
[5] (5 9 11 2 7)
[6] (2 8 11 4 10)

横方向の 9 3 7 5 がすべて異なること。
縦方向の 9 1 3 4 5 2 がすべて異なること。
他の横縦も同様。そういう 6個を作ります。

そして、次のように 5個ずつを
ひとまとめにして 6通りの出力をする。

[1][2][3][4][5] を出力
[2][3][4][5][6] を出力
[3][4][5][6][1] を出力
[4][5][6][1][2] を出力
[5][6][1][2][3] を出力
[6][1][2][3][4] を出力

最後の出力は機械的なことなので、考えなくてよい。

問題は、[1]~[6] のデータが何通りできるか
ということではないのですか?



はい、その通りです。
すいません。貼っていただいたコードがエラーが出てしまうのですが、
これはどの言語で作成して頂けたんでしょうか?

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月27日(月) 14:43
No: 23
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
int main(void)
{
    char s[] = "12345678910//////////";
    puts(s);
    displace(s, 3); puts(s);
    displace2(s, 3); puts(s);
    displace3(s, 3); puts(s);
    displace4(s, 3); puts(s);
}





ごめんなさい。実行できました。
この部分が分からないのですがどういうことなのでしょうか?

Name: たいちう
[URL]
ハッカー(142,150 ポイント)
Date: 2017年11月27日(月) 20:24
No: 24
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

> 1~10の数字を使い、被らない[5][20]の配列で6個のデータ配列を作り出し、
> その6個の配列から5個のデータ配列を取り出して
> 表示する組み合わせを全て表示させる。というものを作ろうと思うのですが、
> どのように組めばよいのか分かりません。
> どなたかご教授願います。


かずまさんの書いてあることがやりたいことならば、
「組み合わせを全て表示させる」というのが不可能ではないかと。

> [1] (9 3 11 7 5)

この表記の1行分で、5040通りあります。
(10 * 9 * 8 * 7 = 5040)
2行分だと私には計算方法が思いつかないのでプログラムで数え上げたところ、
16798320通り。3行分だと、私のPCでは数分では計算できませんでした。
おそらく6行分では、64ビット整数の範囲に入るかどうかといった数です。

数え上げるのも困難なので、全ての組み合わせを表示というのは不可能でしょうし、
意味があるとは思えません。
この配列を何に使いたいのですか?


一応、数え上げるプログラム。
コード[Java]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Main {
    private static int[][] data = new int[4][6];
    private static long count;
    private static int[] usedH = new int[6];
    private static int[] usedV = new int[4];
 
    public static void main(String... arg) {
        count(0);
        System.out.println("count : " + count);
    }
 
    private static void put(int x, int y, int n) {
        int bit = 1 << (n - 1);
        usedH[y] |= bit;
        usedV[x] |= bit;
        data[x][y] = n;
    }
 
    private static void del(int x, int y, int n) {
        int bit = 1 << (n - 1);
        usedH[y] &= ~bit;
        usedV[x] &= ~bit;
        data[x][y] = 0;
    }
 
    private static boolean canPut(int x, int y, int n) {
        int bit = 1 << (n - 1);
        if ((usedH[y] & bit) != 0) return false;
        if ((usedV[x] & bit) != 0) return false;
        return true;
    }
 
    private static void print() {
        System.out.println(count + ":");
        for (int y = 0; y < 6; y++) {
            System.out.print("    ");
            for (int x = 0; x < 4; x++)
                System.out.print(data[x][y] + " ");
            System.out.println();
        }
        System.out.println();
    }
 
    private static void count(int index) {
        int limit = 24;  // 行数×4
        if (index == limit) {
            count++;
//          print();
            return;
        }
 
        int x = index % 4;
        int y = index / 4;
        for (int n = 1; n <= 10; n++) {
            if (canPut(x, y, n)) {
                put(x, y, n);
                count(index + 1);
                del(x, y, n);
            }
        }
    }
}

Name: かずま
[URL]
Date: 2017年11月27日(月) 20:52
No: 25
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

間違っているかもしれないけれど、
すべての組み合わせを表示するプログラムです。
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
 
int a[6][4];
int count;
 
void print(void)
{
    printf("[%d]\n", ++count);
    for (int i = 0; i < 6; i++)
        printf(" %2d %2d 11 %2d %2d\n", a[i][0], a[i][1], a[i][2], a[i][3]);
}
 
int ok(int i, int j, int k)
{
    for (int n = 0; n < 4; n++)
        if (a[i][n] == k) return 0;
    for (int n = 0; n < 6; n++)
        if (a[n][j] == k) return 0;
    return 1;
}
 
void step(int i, int j)
{
    if (j == 4) {
        j = 0;
        if (++i == 6) {
            print(); printf("type ENTER"); getchar(); return;
        }
    }
    for (int k = 1; k <= 11; k++)
        if (ok(i, j, k)) a[i][j] = k, step(i, j + 1), a[i][j] = 0;
}
 
int main(void) { step(0, 0); }

実行結果
コード[Text]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[1]
  1  2 11  3  4
  2  1 11  4  3
  3  4 11  1  2
  4  3 11  2  1
  5  6 11  7  8
  6  5 11  8  7
type ENTER
[2]
  1  2 11  3  4
  2  1 11  4  3
  3  4 11  1  2
  4  3 11  2  1
  5  6 11  7  8
  6  5 11  8  9
type ENTER
[3]
  1  2 11  3  4
  2  1 11  4  3
  3  4 11  1  2
  4  3 11  2  1
  5  6 11  7  8
  6  5 11  8 10
type ENTER
  ...

61323731494502400000通りのはずなので、
1秒間に 100万個出力しても 1943231年以上
かかりますよ。知らんけど。

Name: かずま
[URL]
Date: 2017年11月27日(月) 22:25
No: 26
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

かずま さんが書きました:61323731494502400000通りのはずなので、

すみません。これは間違いです。
もっと多くなります。

Name: Dixq (管理人)
(管理人)
[URL]
ウィザード(1,489,942 ポイント)
Date: 2017年11月27日(月) 23:58
No: 27
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

> この部分が分からないのですがどういうことなのでしょうか?

第一引数を第二引数分ずらしているだけですが、これが分からないということは私が提示したコードは全体的に分からないレベルでしょうか?
どの辺が分からないのか教えてください。

また、問題の仕様をよく考えて聞いてください。
仕様がおかしいので回答者が皆困ったことになっています。

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月28日(火) 12:02
No: 28
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

Dixq (管理人) さんが書きました:> この部分が分からないのですがどういうことなのでしょうか?

第一引数を第二引数分ずらしているだけですが、これが分からないということは私が提示したコードは全体的に分からないレベルでしょうか?
どの辺が分からないのか教えてください。

また、問題の仕様をよく考えて聞いてください。
仕様がおかしいので回答者が皆困ったことになっています。



何故3つずつずらしているのかが分からなかったためです。
説明不足でごめんなさい。


1~10の乱数を用意
[6][5]の配列を用意
3行目は必ず11桁目から
他の行は縦と横が同じ桁目からのスタートがあってはならない
ただし11桁目からのスタートがあってもいい

その後、[5][22]の配列を用意し、生成された行列にあうように
6個のデータ配列を生成する。
生成された6個のデータから5つを取り出し、6通り分表示

これを考えられる全ての場合の組み合わせ分出力させる。



というものを作りたいのですが、教えて頂いた数が私たちの予想以上の時間が
かかるので、

>3行目は必ず11桁目から
>他の行は縦と横が同じ桁目からのスタートがあってはならない
>ただし11桁目からのスタートがあってもいい

行列のスタート位置を変更して、

11 1 11 * *
1 11 11 * *
* * 11 11 1
* * 11 1 11
11 11 11 * *
* * 11 11 11

*は2~10のうちの被らない乱数
このようにすることにきめました。

混乱させてしまい、ごめんなさい。

Name: かずま
[URL]
Date: 2017年11月28日(火) 21:04
No: 29
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

のんのん#24 さんが書きました:というものを作りたいのですが、教えて頂いた数が私たちの予想以上の時間が
かかるので、

>3行目は必ず11桁目から
>他の行は縦と横が同じ桁目からのスタートがあってはならない
>ただし11桁目からのスタートがあってもいい

行列のスタート位置を変更して、

11 1 11 * *
1 11 11 * *
* * 11 11 1
* * 11 1 11
11 11 11 * *
* * 11 11 11

*は2~10のうちの被らない乱数
このようにすることにきめました。

これでも時間はかかるでしょうが、getchar(); を削除
し、ファイルに書き込んで、そのサイズの変化を見ると
面白いかもしれません。
コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
 
int a[6][4] = {
    11,  1,  0,  0,
     1, 11,  0,  0,
     0,  0, 11,  1,
     0,  0,  1, 11,
    11, 11,  0,  0,
     0,  0, 11, 11,
};
unsigned long long count;
 
void print(void)
{
    printf("[%llu]\n", ++count);
    for (int i = 0; i < 6; i++)
        printf(" %2d %2d 11 %2d %2d\n", a[i][0], a[i][1], a[i][2], a[i][3]);
}
 
int ok(int i, int j, int k)
{
    for (int n = 0; n < 4; n++)
        if (a[i][n] == k) return 0;
    for (int n = 0; n < 6; n++)
        if (a[n][j] == k) return 0;
    return 1;
}
 
void step(int i, int j)
{
    if (j == 4) {
        j = 0;
        if (++i == 6) { print(); printf("type ENTER"); getchar(); return; }
    }
    for (int k = 2; k <= 10; k++)
        if (a[i][j])
            step(i, j + 1);
        else
            if (ok(i, j, k)) a[i][j] = k, step(i, j + 1), a[i][j] = 0;
}
 
int main(void) { step(0, 0); }

Name: のんのん#24
[URL]
入門者(2,626 ポイント)
Date: 2017年11月29日(水) 17:56
No: 30
(OFFLINE)

 Re: 配列内[5][15]の組み合わせ.

6回データを表示したら、その内の5個を選び出して出力する方法はどうすればいいでしょうか?

次へ

Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[11人]