• ベストアンサー

多次元配列の工夫

現在、あるプログラミングを作成しています。 そこで4次元配列を使用することが必要になってきました。 ---------------------------------------------- 4次元空間 for(a=・・・a++){ for(b=・・・b++){ for(c=・・・c++){ for(d=・・・d++){ if(ある条件が揃った場合) jouken[a][b][c][d]++; }}}} ---------------------------------------------- 以上のようなことをやりたいのですが、 a~cの値は3桁オーダーなので、メモリを食いすぎ、 処理が桁違いに遅くなり(ページング発生?)、 困っています。 これの解決方法としてはどのようなものがありますかね?たとえば、2次元配列を複数個使うなど。 よろしくお願いします。

  • y_s-u
  • お礼率45% (68/150)

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

  • ベストアンサー
回答No.3

こんにちは、AEと申します。 条件が気になりますね。 私であれば、インクリメントの「条件」をループのなるべく外で設定できないかと考えてみると思います。 つまり、条件が揃った時だけa,b,c,dの添え字を求め、インクリメントを行うという考え方です。 漠然とした答えで申し訳ないのですが、条件によっては、全要素に対してループせずに局所的に処理するようなことも考えられると思うのです。 ※画像処理であれば領域拡大法であるとか。 メモリに関しては、これだけの要領を一挙に確保しようとするとやはり重くなると思います。 もし、動的にメモリが確保されにくいのでしたら、一種のページングですが、自分で必要外のデータをファイルに書き出しておき、必要になったら読み込むという処理を行ってはいかがでしょうか。 少なくとも、自分の好きなタイミングでデータのIOを行うことができますので、ユーザ側にストレスを与えないタイミングでのページング、というコントロールができると思います。 あまり自信がありませんが、要は条件の内容によると思うのです。 必ず全要素に対して上記の処理を行う必要がある(例えば、条件にa,b,c,dの変数が関わっていて、そういうループを作らざるを得ないような)のであれば、このループしかないように思うのです。 →究極的にはハードウェアのパワーアップ(苦笑)。 アルゴリズムを捻りだすのは面白いですね。 頑張ってください。 PS:もしかして、ボリュームデータのラベリング処理とか・・。

y_s-u
質問者

お礼

ありがとうございます。 やるのは画像処理です。 一般化HOUGH変換などです。 なんとか、配列の次元を減らせないかと頭を悩ませて います。しかし、この画像処理は現在のPCスペックでも、 まだ足りないんですねぇ。

その他の回答 (2)

  • nk2
  • ベストアンサー率23% (6/26)
回答No.2

あまり自信がありませんが、 処理速度が遅いのはfor文を4重にもネストしているからなのでは? //---------------------------------------------------------- const int firstA = 0; const int firstB = 0; const int firstC = 0; const int firstD = 0; const int endA = 0; const int endB = 0; const int endC = 0; const int endD = 0; int a = firstA; int b = firstB; int c = firstC; int d = firstD; while(true) {  if(条件) jouken[a][b][c][d]++;  if(d > endD){ d = firstD; b++; }  if(b > endB){ b = firstB; c++; }  if(c > endC){ c = firstC; a++; }  if(a > endA){break};  d++; } //---------------------------------------------------------- 本当にメモリ問題であったのならば jouken配列の型を小さくすればいいと思います。 intは4バイトです。 short intは2バイトです。 charは1バイトになります。 sizeof(jouken) == (型のバイト数)*a*b*c*d; になりますからa,b,c,dの数が大きいなら、 確保するメモリ容量は相当違いが出ます。

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

そのメモリはすべて必要ですか? もしも、「大部分の値が0(あるいは同じ値)」とかだったら、 ・メモリ上で圧縮処理をする。 ・ハッシュ構造でメモリを確保して、0(もしくはデフォルト値)のものは実際には確保しない。 などのことが考えられます。 すべてのメモリが必要であるならば、 どうしてもページングは発生すると思います。 あるいは、「値の最大値が16」などの条件があれば、 1バイトに2つの値を押し込むことによって、半分に圧縮できます。

関連するQ&A

  • 多次元配列

    初歩的な質問ですみません。 PHPプログラミングでの質問です。 仮に、多次元配列Aに、 Array( [0] => Array ( [0] => 6 ) [1] => Array ( [0] => 2 [1] => 1 ) [2] => Array ( [0] => 0 [1] => 5 [2] => 4 ) ) 多次元配列Bに、 Array( [0] => Array ( [0] => りんご ) [1] => Array ( [0] => ぶどう [1] => パイナップル ) [2] => Array ( [0] => みかん [1] => すいか [2] => メロン ) ) のように値が入っている場合、配列Aの値を参照して 値の大きいものから順に、それに対応する配列Bの値を取り出し、 あたらしい配列Cに代入する処理の書き方を教えて下さい。 上記の例ですと、配列Cが、 Array ( [0] => りんご [1] => すいか [2] => メロン [3] => ぶどう [4] => パイナップル [5] => みかん ) となるようにしたいです。 よろしくお願いします。 長文失礼しました。

    • ベストアンサー
    • PHP
  • 多次元配列の扱い方

    PHPバージョン5.2.4を使っています。 次のような文字列が入っている多次元配列を foreachなどのループを使ってその値を取り出して扱いたいのですが、 取り出した値には配列(二次元以降の値)も含まれてるので 簡単には取り扱いできません・・・ print_rやvar_dumpを使えば値は全て表示されるのですが、 あくまで表示ではなくて値を取り扱いたいのです。 そのようなことができる関数などはあるのでしょうか? $arr[0][0] = 'a'; $arr[0][1] = 'b'; $arr[1] = 'c'; $arr[2][0][0][0] = 'd'; $arr[2][0][0][1] = 'e'; foreach ($arr as $value) { $value//←ここで値を扱いたいけど、配列も含まれてるので・・・ }

    • 締切済み
    • PHP
  • 多次元配列の一次元目の最大値の求め方

    多次元配列の一次元目の最大値の求め方 下記のような多次元配列(ちなみに、これって二次元配列ですか?)があるとき、 常に、「一次元目の最大値+1」を返すようにしたいのですが、 どうすればよいのでしょうか? $data[0][0]とか$data[1][0]とか$data[2][0]とかの最大値の意味です。 下記の例でいくと、一次元目の最大値が3なので、数値の4を返したいのですが…、 ■$data 1,0,A1,B1,C1 2,5,A2,B2,C2 3,0,A3,B3,C3 3,2,A4,B4,C4

    • ベストアンサー
    • PHP
  • 4次元空間の4つのベクトルが張る空間が1次元、2次元、3次元、4次元である条件

    4次元空間にゼロベクトルでない4つのベクトルを考えます。 a↑=(a[1],a[2],a[3],a[4]) b↑=(b[1],b[2],b[3],b[4]) c↑=(c[1],c[2],c[3],c[4]) d↑=(d[1],d[2],d[3],d[4]) とします。 これらのベクトルで張られる空間が1次元、2次元、3次元、4次元である条件を求めたいのです。 各ベクトルを並べて行列(a↑ b↑ c↑ d↑)を作り、基本変形で階数を計算するというアルゴリズムではなく、各成分の代数的な関係を求めたいのです。 4つのベクトルで張られる空間が4次元のとき、超体積が0ではないので、行列式 |a↑ b↑ c↑ d↑|≠0 4つのベクトルで張られる空間が1次元のとき、すべて平行なので、 a↑∥b↑∥c↑∥d↑ a[1]:a[2]:a[3]:a[4]=b[1]:b[2]:b[3]:b[4]=c[1]:c[2]:c[3]:c[4]=d[1]:d[2]:d[3]:d[4] (a[1]/a[4],a[2]/a[4],a[3]/a[4])=(b[1]/b[4],b[2]/b[4],b[3]/b[4]) =(c[1]/c[4],c[2]/c[4],c[3]/c[4])=(d[1]/d[4],d[2]/d[4],d[3]/d[4]) このあと、一つの式にする、つまり、イコールを一つだけにしてきたいのですが、複雑そうです。行列式またはシグマ記号を使って、表記できないでしょうか? 4つのベクトルで張られる空間が2次元、3次元のとき、それぞれの各成分にはどういった関係式があるのでしょうか?

  • 二次元配列のポインタについて教えて下さい

    今日はCの配列のポインタについて質問いたします、宜しくお願いします。 1次元の配列からは、 =================================== int *p , a={1,2,3}; p = &a; printf("%d\n" , p[1] ) ; printf("%d\n" , *p[1] ) ; ===================================== でaの値がとれますが、 二次元の配列では下のような書き方ではエラーになります。 何故でしょうか、どう書いてやればいいのでしょう。 ===============================================  printf("%d\n" , pbb[1][1] ) ;  printf("%d\n" , *pbb[1][1] ) ; =============================================== 宜しくお願いします。

  • 多次元の配列を[ ]で括って見やすくトレースするには?

    多次元の配列を[ ]で括って見やすくトレースするには? 何次元か特定される配列ならばforなどで次元の数だけ繰り返せばできるとは思うのですが そうでないときにも [ [ [a,b,c,...],[],[],...],[],[],... ] のように隣り合う要素(配列)との切れ目が見やすいようにトレースする方法はありますか? プログラムには影響しませんが、トレースすると1次元の配列と同じように , だけで区切られてトレースされてしまい見にくいですので 配列が何次元か返させる関数など書ければ良いと思うのですが FlashPlayer10、ActionScript3.0です 質問の意味理解していただけるでしょうか お願いします

    • ベストアンサー
    • Flash
  • 多次元配列のカウントのしかた

    すみません、質問させてください。 $array1:1次元配列 $array2:2次元配列 1次元配列のカウント(要素数)をしるには count($array1) とすれば取得することができますが、 2次元配列のカウントを取得するにはどのように すればいいのでしょうか?そんな関数はありますか? $array2のデータの中身 $array[0][0] = 'a'; $array[0][1] = 'b'; $array[1][0] = 'c'; $array[1][1] = 'd'; $array[2][0] = 'e'; $array[2][1] = 'f'; この場合、3という値が欲しいのですが・・・ 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • 2次元配列について

    プログラミング初心者です。2次元配列のイメージがつかめません。教えてください。 例えばExcelの表があり、A列に名前のデータ、B列にその人の住所のデータがあったとします。プログラミングで1次配列の値だけ取得するような処理が書かれていた場合、名前のデータだけを取得しているのでしょうか?因みに$var[0]というように数字ではなく、何かを示す名前になっています。例えば$var[name0]や$var[name1]のようになっています。これが$var[name0][place0]や$var[name1][place0]みたいになっていたら住所のデータを取得するのでしょうか?

    • ベストアンサー
    • PHP
  • 2次元配列への値の代入

    C言語の初心者です。 以下のようなプログラミングをしたいのですがどう組めばいいのでしょう。 2次元配列に値を代入する。 ただし条件が成立するときだけ。 そこで以下のようにプログラムを組みましたが、 どうも、うまくいきません #include<stdio.h> void main(){ int k,l,m; int ans[5][10]; l=0; for(k=0;k<5;k++){ if(k==4){ ans[k][l]=1; l++; printf("%d\n",ans[k][l]); } } } kはインクリしたいのですが、lは条件が成立するときだけインクリしなければならないのですが、 どうプログラミングすべきなのでしょうか?

  • PHPで2次元配列を1次元配列にしたいのですが、わからないので教えてく

    PHPで2次元配列を1次元配列にしたいのですが、わからないので教えてください。 例えば2次元配列を以下のようにします。 $ss[0][0]=a $ss[0][1]=b $ss[0][2]=c $ss[1][0]=あ $ss[2][0]=い $ss[3][0]=う これを以下のような1次元配列にしたいです。、 $ss[0][0]→$g[0],$ss[0][1]→$g[1],$ss[0][2]=$g[2] $ss[1][0]→$h[0],$ss[2][0]→$h[1],$ss[3][0]=$h[2] よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう