• 締切済み

配列のサイズを決めないプログラム

プログラムの作成時に配列のサイズを決めないでプログラムの実行時に決めるという場合があると思います。 1.可変サイズとして配列の宣言 2.プログラム開始後、何らかの情報でサイズを決定する 3.確保された配列にデータを読み込ませたりして使用する ここで質問ですが、データを読み込ませて配列のサイズが決まる場合、上記の方法では不成立のように思います。2と3が逆だからです。処理するデータに応じて配列のサイズを変更する方法を教えて頂きたいのですが。そのような処理が可能になるとプログラムがデータの量と無関係(もちろん限度あり)となり汎用化されると思うのですが。どのようにするのでしょうか。基本はfortran95ですが、Cでの処理でも参考になるかと思います。

みんなの回答

  • unokwave
  • ベストアンサー率58% (966/1654)
回答No.3

2の「何らかの情報」を「データをバイトなど、構造の最小単位で次々と読み込んで、サイズ解析を予め行う」 という方法を採っている事もあります。 ランダムアクセスが可能ならシークポイントを変更し、シーケンシャルなら必要箇所以外を読み飛ばす事でできます。 処理速度よりも、リスト構造の構造情報自体も塵も積もればで馬鹿にならない時に採られる方法です。 読み込み処理ルーチンの引数に、解析動作なのか本体読み込み動作なのかを示すフラグを設ければ、最小の手間で動作を変えられます。

  • wormhole
  • ベストアンサー率28% (1619/5652)
回答No.1

「2.」で完全にサイズを決定するんでなくて 2. 読み込むデータがあるなら配列のサイズを増やす。読み込むデータがないのなら終了。 3. 増やしたサイズ分読み込む 4. 「2.」に戻る とすればよろしいかと。

skmsk1941093
質問者

お礼

回答ありがとうございます。以下のような感じでしょうか。 1.仮に読んで見る。 2.読み込めるからデータがある。 3.だったら配列を増やす。 4.1で仮に読み込んだデータがあるのでそれを増やした配列の最後に入れる 私は読み込むループの内部で配列のサイズを変更できると思っていなかったのですが、できそうですね。ありがとうございます。

関連するQ&A

  • 動的配列の使い方の問題

    プログラムには動的配列というものがあり、配列なのですが、最初の宣言でサイズは指定しない(型は指定すると思いますが)というような動作ができるのだろうと思います(それ以外もあるかもですが)。 私が目指しているのはデータの総数がわからないけれど、データファイルを読み込んで総数をカウントしたらわかるのでそれを使ってメモリを確保するというようなことです。事例集を見ると以下のようなものはあります。 allocatable a(:) ..... データファイルを開いてカウントしたら100だった ..... allocate(a(100)) この使い方ってあんまりご利益がないように思います。カウントしたら100だったということですが、その時はデータをとりあえず読んでいるわけです。 配列サイズ100とわかって実際にアロケートしないと配列は利用できないものなのでしょうか。 これに関連して質問ですが、サブルーチンとか関数とか副プログラムに配列を渡して処理する場合、サブルーチン側の配列(仮引数)の型、サイズを指定しない方法があるでしょうか。メイン側で決めたものに従いますということなのですが。 例えばサブルーチン側の仮引数BについてB(*)などとしていたらメイン側の指定通りになっているということになるのでしょうか。動的な配列ということでお尋ねしているのですが、副プログラムの仮引数の配列がサイズ依存が消えたように見えるからこちらの方が動的に見えるのですが。サイズに関してはメインで宣言したらどうにでも対応します、という弾力性があります。もちろ使いまわしも容易になりますが。 言語ですが、お気づきとは思いますが、Fortranです(ハズイ感じ)。その他の言語の仕様でも参考になります。よろしくお願いします。

  • プログラム言語の動的配列について

    動的配列という場合、配列のサイズがプログラム動作中に変化する、という意味でしょうか。 それとも、プログラム作成時に配列サイズが指定されておらず、外部のデータを読み込んでその時点でサイズが確定するという場合もあるかと思います。おなじことでしょうか。 なお、配列のサイズが指定されていないプログラムがあるとして、実行開始したあとから指定された配列サイズがメモリ容量とか制限によって上限値があるということにはなるかと思います。 また、大き目に配列を用意して実際に使用する場合、その一部しか使わないというのは通常のことだと思います。そのような場合は全く無関係だと思います。 データのサイズが違っても同じプログラムが使えるので1つ作ればあちこちに応用できることになると思います。このあたりのことがクリアになると同じことをするプログラムは1つだけあればいいということになります。 一応、C,C++,Fortran(77,95)という昔からある言語で、ということですが。 よろしくお願いします。

  • 配列サイズを明示せずサブルーチンに渡す方法

    プログラムのメインの方で2次元、3次元の高次元配列を設定してそれをサブルーチンに引き渡すことを考えています(しょっちゅうやっていることですが)。 この場合、サブルーチン側に汎用性を持たせるためにできるだけ配列のサイズを自動で渡すようにしたいと思っています(メインが変わるとそれに応じて自動対応)。そうしないとサブルーチンが汎用化せず、ケースバイケース(メイン側の配列のサイズが変わる場合それに応じてコードを書き変えなければならない)に応じなければならず、うっかりミスの間違いもおこりそうです。 配列のサイズを決めないサブルーチンの書き方を教えて頂きたいのですが。 なお、今回は配列はデータとして参照するだけで書き換えることはありません。 言語ですが、”サブルーチン”というだけあってFortranです。(Cのカテゴリだと答えを頂けるかなと思っているのですが。他に適当なところも無いようですが)

  • プログラムでの配列の渡し方

    ここではフォートランの問題としてお尋ねします。(フォートランのカテゴリがないのでプログラムの専門家に聞けそうなカテゴリに質問してます。) dimension a(100,100) ... call abc(a) ... stop end subroutine abc(b) dimenison b(100,1) ... return end というようなプログラムがあります。メインの方でa(100,100)と宣言してサブルーチンではb(100,1)で受けるというような処理です。 このようにメインとサブで配列のサイズが異るのはどのようなレベルで許容されるものでしょうか。考え方がわからないのでお尋ねします。私は厳密にサイズを合わせると思っていました。しかしそうだとサブルーチンの使い回しができなくなります。このような問題はC言語の配列の先頭のアドレス云々という問題と似ているのですが。2次元配列ということがわかっていて片方のサイズがわかると自ずからもう片方のサイズがわかるということなのでしょうか。 まとめますと、以下のような点がわからないということです。 1.メインとサブで配列サイズが異なっても問題ないやり方 2.サブ側が動的に対応できるようにするプログラムの書き方(同じサブルーチンだけど、呼び出すメイン側の配列サイズに自動で対応する方法) *などを使うのだろうと思いますが。 この部分はしっかり理解しないと大怪我するところなので確認したいと思っています。 (実験して試すというのではなく、仕様としてどうかということですが) よろしくお願いします。

  • エクセルVBA 必要な数だけ配列を確保する方法は?

    Dim a(10,1)と宣言して、セルにある10個のデータを配列aに代入したいのですが、セルに何個のデータがあるかはプログラムを書いているときには分かりません。 セルにあるデータは、プログラムを走らせるとn個あることが分かります。 それからDim a(n,1)と宣言できれば、必要な数の配列が確保できるのですが、このように必要な数だけ配列を確保するにはどうすれば良いのでしょうか?

  • 配列のサイズを動的に拡張

    お世話になっております。 配列のサイズを動的に拡張について悩んでおります。例えばint x[5]という配列があって、データが埋まったら動的にx[6]にする・・ っといったものです。自分で試行錯誤した結果、以下のようなプログラムを作成しました。 int *data,count=0,num=10;// グローバル変数 // 配列にデータを加える関数add void add(int t){  if(count+1>num){ // サイズを超えたら配列をサイズを+1    int i,*tmp_data;    tmp_data = new int [count];    for(i=0;i<num;i++) tmp_data[i] = data[i]; // 一時的に保存    delete[] data; // 古いのを消す    data = new int [num+1]; // 新しく作る    for(i=0;i<num;i++) data[i] = tmp_data[i]; // 新しいのにコピー    num+=1; // 最大値をプラス    data[count]=t;    delete[] tmp_data;  }  else data[count]=t;  count++; // 入力されたカウントをプラス } main関数内で、data = new int [10];と宣言し、add(3);のように使用しています。またnewのメモリ確保のエラー処理は省いております。 動くことは動くのですが・・ご覧の通り、グローバル変数が3つになり、データをコピーしたりと、複雑になってしまいました。 もっと簡単に出来るのでは・・っと思い質問させて頂きました。 こうすれば、もっと簡単になるよ!など。。ご回答頂ければ幸いです。

  • 配列のサイズを動的に指定したい。

    現在FeliCaを使ったプログラムを作っているのですが、 FeliCaから読み込んだデータを各配列にサイズぴったりで格納したいんですが、読み込むデータによって配列のサイズが違うため、あらかじめ配列のサイズを指定しておくことができません。  例1「012 34567 89]    例2「01 2345678 9」   a[3]=012           a[2]=01   b[5]=34567          b[7]=2345678   c[2]=89            c[1]=9 というように空白で区切った文字列を各配列に格納したいのです。 なにか良い方法はないでしょうか? ソフトはVisualStudio6.0を使用しています。

  • サイズがいろいろの2次元配列を数多く発生させる方法

    2次元配列は、すなわちマトリックスということになります。2次元配列を数多く発生させるために3次元配列が定義できると楽になります。しかし、2次元のマトリックスのサイズが異なる場合、どうなるでしょうか。 例えばA(i,j,k)ですが、i=1の場合、i=2の場合、....でj,kの取る範囲が異なるということなのですが。最大にとっておけばいい、ということにはなりますが、使わないメモリを確保することにちょっと抵抗があるのですが。言語はFortranなので難しい面があると思います。C言語だったらmallocを使うんだろうと思いますが。

  • Segmentation Fault (メモリ制限?)

    Segmentation Fault (Fortranのプログラム)に関して質問です。 あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、 大きなデータを扱うようになった場合Segmentation Faultとなります。 宣言している配列サイズを超えた部分のアクセスなどでSegmentation Faultが出ることがあるようですが、どうやらそのような現象ではなく、 メモリ制限にひっかかっている感じがいたします。 エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を している部分のようです。(下の例ではtest bが表示れる以前に止まります。) !-------------------------------------------------- subroutine calc_tri( ) implicit none real*8 data1(3,200000) !<--- ここでエラー --> write(6,*) 'test b' !-------------------------------------------------- このような場合、配列データを減らす以外にどのような対策が あるのでしょうか? あるいはメモリ制限になりそうなデータ数が分る方法などあります でしょうか? 環境は linux (CentOS) intel Fortran Compiler version 8.0 Mem: 1GB topコマンドにて Memの使用割り合いは10%にもならないのですが コンパイラによるメモリ制限などもあるのでしょうか? subroutine内の配列の宣言はデータ数より多くとっていることは確認しています。

  • 配列のサイズが明示的でない計算について

    Fortranを例にとった場合、 行列A,Bの積Cを計算する場合、例えば以下のようなループで計算していました。(Fortran77) do i=1,10 do j=1,10 sum=0.0 do m=1,10 sum=sum+a(i,m)*b(m,j) enddo c(i,j)=sum enddo enddo それが今では、以下1行です。(Fortran95) c=matmul(a,b) 配列1つ1つの成分について計算する必要がないと言えそうです。Pythonなんかは全部こういう思想ですね。 プログラム言語はすべてこういう方向に進んでいるように思えます。 これがやや不安に思えるところがあります。配列のサイズを指定していないのでどこまで使って計算しているかわからないからです。 古い方(上段)では配列のサイズや上限を指定しているので、指定しているところより先がどうなっていてもとりあえず被害はありません。 しかし、サイズについてのケアがないと思いがけないような計算をしてくるんじゃないかと思うのですが。計算のバグ取のときここ大丈夫かな?となって疑心暗鬼ということにならないかと思うのですが。 配列の最大値なども関数1つと言う感じですが、どこまでの範囲での最大なの?と聞きたくなるわけですが。 いかがでしょうか。

専門家に質問してみよう