C言語の配列操作のスマートな方法を教えてください

このQ&Aのポイント
  • C言語で多次元配列を操作する際に、特定の条件を満たす要素をランダムに選びたい場合、効率的な方法が知りたいです。
  • 現在は、64要素の2次元配列を作成し、for文で要素を解析して特定の条件を満たす要素の番号を格納していますが、この方法では無駄が多い気がします。
  • もっとスマートな方法やワンライナーで実現できる方法があれば教えてください。
回答を見る
  • ベストアンサー

c言語の配列操作

c言語で、hairetu[8][8]があったとして、その中でいくつかの中に1が入っていて、そのほかは0が入っているとします。 0 1 2 3 4 5 6 7 0|1 0 0 0 1 1 1 0 1|1 0 0 0 0 0 0 1 2|0 1 1 0 1 0 1 1 3|・・・・・・・・・・・・ 4|・・・・・・・・・・・・ 5| 6|・・・・・・・・・・・・ 7|0 1 1 0 0 0 0 1 という具合です。 そのとき、ランダムで1を1箇所しかない状態にしたいのですが、 自分が考えた方法だと無駄が多いので、もっとスマートな方法はないかと思い質問させてもらいました。基本的な質問なのですがよろしくお願いします。 以下自分が考えた方法 [64][2]の配列を作成し、上記の[8][8]の配列をfor文で解析し、1が入ってるところの番号を配列[64][2]に格納する。 乱数を使い、ひとつだけ選択する。

質問者が選んだベストアンサー

  • ベストアンサー
  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.2

カテゴリをC言語にしてらっしゃいますが、その問題はC言語に限った問題ではないでしょう。 まず、最適なアルゴリズムを選ぶのに重要なことは、0と1の分布がどうなっているかです。1の数が非常に少ない場合は、質問者さんの出したようなアルゴリズムでするしかありません。 1の割合がもっと多い場合は、先に位置を乱数で選択して、そのあとその位置の値が1かどうか判定するという乱択アルゴリズムのほうが効率がいいでしょう。 他には、配列に入っているという事ならば、並列演算で1の入っている領域を限定出来れば効率化できるかもしれません。

myarukus
質問者

お礼

回答ありがとうございます。 確かによく考えたら言語関係なかったですね カテゴリーミスすいません さらに1の数の多少を書いておらず、条件が不足しておりました。 重ねてすいません 図ではあんなに調子づいて1を書いてしまいましたが、 数はほとんど一桁に成りそうなので、 自分のやり方でやってみます。 また、並列演算というのはやったことがないので調べてみようとおもいます。

その他の回答 (2)

回答No.3

「ランダムで1を1箇所しかない状態にしたい」というだけなら、初期値は一切関係ありません。 全体をゼロクリアしてからランダムに1か所だけを1にすればよいでしょう。

myarukus
質問者

お礼

回答ありがとうございます。 説明が下手くそでした。 大変申し訳ないです。 全体からではなく、1が入っていた場所から ランダムで一ヶ所だけ1にする と説明するべきでした。

  • k_kota
  • ベストアンサー率19% (434/2186)
回答No.1

自分で考えた結果があるので回答します。 条件足らなかったら補足してください。 あえてざっくり書きますけど、 「とりあえず1マス選んで、1なら他を全部0にする、0だったらもう一回選ぶ」 これだと確率のばらつきもよさそうです。 ちなみに、計算機的に考えると、場所を決めたあとは 全部まっさらに0にしてから1の場所を改めて1にする方が多分キレイで早いです。

myarukus
質問者

お礼

回答ありがとうございます。 1の数が多い時はそのやり方が良さそうですね 大変参考に成りました。

関連するQ&A

  • ファイル操作と配列について

    Java言語で,テキストデータを読み込み,それを配列に格納したいのですが, どうすればいいのでしょうか? 配列に格納するときに,うまい具合にfor文などで一気に格納したいです。

  • 配列のことでなのですが

    配列で先頭から順番に文字列を格納していきたいのですがどのような方法があるでしょうか? ただforループなどで順番に繰り返すのではなくて、文字列を入力する度に配列の最後尾に文字列を格納していきたいのですが、 例えば for(i=0;i<=10;i++){ scanf("%s",hairetu[i]) } のような方法ではなく配列の中に文字列を前から順番に格納したいです。 詳しい方は知識をかしていただけるとありがたいです。

  • C言語のプログラミング作成なのですが....

    C言語の問題なのですが、大きさ100の配列に1から10の一様乱数を格納しヒストグラムを*を使ってプログラミングするというものなのですがさっぱりわかりません。わかる方どうかよろしくお願いします。

  • C言語配列

    c言語初心者ですよろしくお願いします。 ファイルから読み込んだ100万件のデータをstaticを使わずに配列に格納したいのですが。 どういった方法があるでしょうか? 私のpcでは変数名[10000]くらいがエラーのでない限界みたいです。

  • 配列の並びかえごにFor文使用

    いつもお世話になっております。 今回、配列の要素数に応じて順番を並び替へ、要素数の多いのから少ないものへのforループに挑戦することにしたのですがルーチンが思い浮かばず投稿させていただきました。 DBから 条件1で検索し、その条件でヒットしたid列の値を$hairetu1に格納しております。 条件2で検索し、その条件でヒットしたid列の値を$hairetu2に格納しております。 条件3で検索し、その条件でヒットしたid列の値を$hairetu3に格納しております。 条件4で検索し、その条件でヒットしたid列の値を$hairetu4に格納しております。 条件5で検索し、その条件でヒットしたid列の値を$hairetu5に格納しております。 最大5つの条件で検索できるようにしております。($hairetu変数は全て配列変数として使用しております) 条件1で検索した再に、$hairetu1には、1,2,4という値(id値)が入っており、 条件2で検索した再には、$hairetu2に、1,4という値が入っています。 条件3で検索した再には、$hairetu3に、1,2,3,4という値が入っています。 条件4で検索した再には、$hairetu4に、9999という値が入っています。 条件3で検索した再には、$hairetu5に、1,2という値が入っています。 ※各条件で検索した際に、ヒットしたid数が0の場合、nullが入らないように初期化の時点で9999をセットしております。$hairetu=array(9999); 今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] の結果、1と2を最終的に$result_hairetuに格納したいのです。 考えた方法は、 For(i){ for(j){ for(k){ for(l){for(m){ if(hairetu[i]==hairetu[j] && hairetu[i]==hairetu[k]・・・,hairetu[l] ==hairetu[m]){array_push($result_hairetu,hairetu[i])}}}}}} ※i・・・ (i=0;i<count(hairetu1);i++) という方法で、5つのfor文でループし、ifで比較し同じであればresult_hairetuに格納するという手法をとろうとしたのですが、条件2で検索した結果が、1,2の二つであるため、二つ目のfor文を二回走ったところで抜けてしまい処理が途中で終わってしまいます。 途中で抜けるのを防ぐために以下のように配列を並び替えて、 For分で使用するという流れを作りたいのです。 また、今回、hairetu2と5の要素数が同じなのときはどのようにセットしたらよいかもわかりません。要素数が同じである場合はどちらが先でもかまいません。 for(hairetu4){for(hairetu2){for(hairetu5){for(hairetu1){for(hairetu3)}}}} このループの作り方がわかる方がいらっしゃいましたらご教授のほうお願いできないでしょうか?よろしくお願いします。

    • ベストアンサー
    • PHP
  • VBAの配列の格納について

    エクセルのVBAで、セルのデータを配列に格納するスピードを向上したいと思います。 例えば、A1~A10000のセルにデータを書き出す場合、 For 行番号 = 1 To 10000 Cells(行番号, 1).Value = 1 Next よりも、一旦、配列に書き込んだ後、一気にセルに書き込んだ方法が早いのですが、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = 1 Next Range("A1:A10000").Value = HAIRETU() 今度は、A1~A10000に書き込んだデータを、再度、配列に格納する場合、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = Cells(行番号, 1).Value Next とすると時間がかかるので、 HAIRETU() = Range("A1:A10000").Value というような処理をしたいのですが、うまくいきません。 よい方法がありましたら、ご教授ください。 よろしくお願いします。

  • 乱数を配列へ格納(JavaScript)

    乱数を重複しないよう8個配列へ格納したいのですが、 格納の時点でエラーが発生します。 「オブジェクトでサポートされていないメソッドまたはプロパティです」 なぜでしょう? どなたかご教授下さい。 numbers = new Array(); // 空の配列宣言。 function make() { while(numbers.length < 8){ check = true; number = Math.floor(Math.random() * 100);// ランダムに0~99までの整数を取得。 for(i = 0; i < numbers.length; i++) { // 今取得したものと同じ乱数がないか、 if(number == numbers[i]) { // 配列の中身全てと比較。 check = false; } } if(check) { numbers.push(number); // 取得した乱数を配列に格納。 } } }

  • C#についてです

    乱数を発生させて、折れ線グラフを作りたいのですが、分かりません。 乱数を15個、100までの範囲で発生させたかったので、下のように書いては見ました。      Random rnd = new Random(); for (int i = 0; i < 15; i++) { rnd.Next(100); } この乱数を、配列にして、グラフを作りたいと思っています。 配列にするにはどうすれば、よいのでしょうか? お願いいたします。

  • c言語の全角文字を配列に格納について

    C言語を使ってchar配列に漢字を格納したいです。東海道新幹線の18駅を一駅ずつ漢字で格納したいと考えています。しかし、情報量が多いので格納がうまくいきません。漢字で格納する方法があれば教えていただきたいです。お願いします。

  • C言語での配列順序を変えたい

    C言語で遺伝的アルゴリズムを作ろうと思っています。そのときに「配列の中の値を調べてそれを数字の高い順に別の配列に入れる」というので、並び替える方法がわかりません。 for(i=0;i<10;i++){ //並び替える前をy、並び替えた後をzとする for(j=0;j<10;j++){ if(y[i] < y[j]){ z[i+1] = y[i]; }else{ z[i-1] = y[i]; } } } としてやってみたら、よく考えると上の配列に値があった場合、重なってしまうので、実際表示して見たところ同じような数字が出てきました。

専門家に質問してみよう