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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#1

投稿記事 by のんのん#24 » 10ヶ月前

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通りの組み合わせを表示させ、
全ての組み合わせを表示させるプログラムを作りたいです。
どうかよろしくお願いします。

よもやま
記事: 68
登録日時: 2年前
連絡を取る:

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

#2

投稿記事 by よもやま » 10ヶ月前

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#3

投稿記事 by のんのん#24 » 10ヶ月前

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

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

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

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

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

かずま

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

#4

投稿記事 by かずま » 10ヶ月前

のんのん#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文字になっていますが、これでいいのですか?

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

アバター
usao
記事: 1445
登録日時: 5年前

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

#5

投稿記事 by usao » 10ヶ月前

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

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

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

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

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#6

投稿記事 by のんのん#24 » 10ヶ月前

「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文字で間違いないです。

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

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#7

投稿記事 by のんのん#24 » 10ヶ月前

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個のパターンを表示させたいです。

アバター
usao
記事: 1445
登録日時: 5年前

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

#8

投稿記事 by usao » 10ヶ月前

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

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

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

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

かずま

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

#9

投稿記事 by かずま » 10ヶ月前

かずま さんが書きました: それから、何の配列ですか?
 数値なら 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 の個数は乱数で決めるのでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1655
登録日時: 8年前
住所: 北海道札幌市
連絡を取る:

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

#10

投稿記事 by Dixq (管理人) » 10ヶ月前

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

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

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#11

投稿記事 by のんのん#24 » 10ヶ月前

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

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

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

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

コード:

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;
}

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#12

投稿記事 by のんのん#24 » 10ヶ月前

それから、何の配列ですか?
 数値なら 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は乱数であっても初期設定でも構いません

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#13

投稿記事 by のんのん#24 » 10ヶ月前

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

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

何故ウソを言われるのでしょうか?
サイト管理者(私含めて5名)はアクセス元の情報が分かるのでウソを書かないて下さい。
せっかく時間かけてソースコードまで書いたのに返信もなく「別の人の物だ」と言われると回答者としては悲しいです。
私の予測が違っていたなら元のトピックで補足して頂きたかった。
申し訳ございません。学内の共用PCを貸し合い、これを3人で考えてるため似た質問をしていたみたいです。
本当にごめんなさい。

アバター
Dixq (管理人)
管理人
記事: 1655
登録日時: 8年前
住所: 北海道札幌市
連絡を取る:

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

#14

投稿記事 by Dixq (管理人) » 10ヶ月前

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

しかし、他の人もいっているように質問内容の仕様が明確でないので、明確に回答できない部分が多いです。
やりたいことを想像で作ってみました。

コード:

#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);
    }
}
数値を代入しているという割には文字を代入しているようにも

実行結果

コード:

////////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通りの表示をするということでいいのでしょうか?

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#15

投稿記事 by のんのん#24 » 10ヶ月前

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

////////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が入っていても問題ないものとする)
が被らないものというものにしたいのです。(その分の組み合わせの数が減るので)

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

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

アバター
Dixq (管理人)
管理人
記事: 1655
登録日時: 8年前
住所: 北海道札幌市
連絡を取る:

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

#16

投稿記事 by Dixq (管理人) » 10ヶ月前

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

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

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

かずま

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

#17

投稿記事 by かずま » 9ヶ月前

私の理解を書きますね。

////////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] のデータが何通りできるか
ということではないのですか?

かずま

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

#18

投稿記事 by かずま » 9ヶ月前

かずま さんが書きました: 1行は 12345678910 という 11文字の前後に
0個以上の / があります。
左右合わせて 10文字です。
すみません。用語の不整合です。
「前後」と「左右」はどちらかに統一してください。

かずま

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

#19

投稿記事 by かずま » 9ヶ月前

オフトピック
Dixq (管理人) さんが書きました:

コード:

//引数の配列の中身を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 回繰り返すのは効率が悪そうです。

コード:

#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);
}
実行結果

コード:

12345678910//////////
///12345678910///////
//////12345678910////
/////////12345678910/
10//////////123456789

かずま

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

#20

投稿記事 by かずま » 9ヶ月前

かずま さんが書きました: 5行のデータが (9 3 11 7 5) と表せました。
表示を数の並びで表せましたが、その逆は簡単です。

コード:

#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);
}
実行結果

コード:

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#21

投稿記事 by のんのん#24 » 9ヶ月前

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

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

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

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

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

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

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

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#22

投稿記事 by のんのん#24 » 9ヶ月前

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

////////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] のデータが何通りできるか
ということではないのですか?

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#23

投稿記事 by のんのん#24 » 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);
}



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

たいちう
記事: 418
登録日時: 8年前

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

#24

投稿記事 by たいちう » 9ヶ月前

> 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ビット整数の範囲に入るかどうかといった数です。

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


一応、数え上げるプログラム。
► スポイラーを表示

かずま

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

#25

投稿記事 by かずま » 9ヶ月前

間違っているかもしれないけれど、
すべての組み合わせを表示するプログラムです。

コード:

#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); }
実行結果

コード:

[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年以上
かかりますよ。知らんけど。

かずま

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

#26

投稿記事 by かずま » 9ヶ月前

かずま さんが書きました:61323731494502400000通りのはずなので、
すみません。これは間違いです。
もっと多くなります。

アバター
Dixq (管理人)
管理人
記事: 1655
登録日時: 8年前
住所: 北海道札幌市
連絡を取る:

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

#27

投稿記事 by Dixq (管理人) » 9ヶ月前

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

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

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

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#28

投稿記事 by のんのん#24 » 9ヶ月前

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のうちの被らない乱数
このようにすることにきめました。

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

かずま

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

#29

投稿記事 by かずま » 9ヶ月前

のんのん#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(); を削除
し、ファイルに書き込んで、そのサイズの変化を見ると
面白いかもしれません。

コード:

#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); }

のんのん#24
記事: 19
登録日時: 10ヶ月前

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

#30

投稿記事 by のんのん#24 » 9ヶ月前

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

返信

“C言語何でも質問掲示板” へ戻る