• ベストアンサー

大きな配列データを複数ある場合のデータ保持の方法

indowsXP VC++.net2003で開発をしています。 100*100程度の2次元配列が20から50程度ある場合、データはどう保持しているのが良いのでしょうか? 同時に使うのは1個のみですので、すべて宣言するのはメモリの無駄だと思っています。 思いついた方法は 1.テキストファイルに保持しておく 2.データベースに保持しておく の2つですが、ユーザーに配列の中身が見られたり変更されたりするのも困るので1の方法は却下しました。 2の方法ですがデータベースを用意するのは無理なのであきらめました。 また、配列データはツールから作成しており、以下のように宣言しやすいように表示されます。 値をひとつひとつ代入して初期化するのも大変なので、できればこの表示をいかしたまま、 必要な配列を取り出して扱うということをしたいのですが、何か良い方法はないでしょうか? それともint型の100*100の2次元配列 50個程度なら宣言したほうがいいのでしょうか? int test[32][32] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 以下省略

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

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

int型の100×100の2次元配列50個程度なら数MBだと思うので, メモリが厳しい環境でなければ宣言してしまっても問題ないと思います. メモリの事を気にするのであれば, 動的に宣言するのが一般的だと思います.

lilillii
質問者

お礼

解答ありがとうございます。 ローカル宣言している関数を用意して、 そこからコピーすれば必要な分だけメモリを使用できそうですね。

その他の回答 (2)

  • rot-N
  • ベストアンサー率27% (118/432)
回答No.3

intが、2もしくは4バイトで、100×100だから1万、これが50個。 4×100×100×50=2000000ですよね? およそ2000キロバイトで2メガバイト。いまならファイルの読み書きでもキャッシュに入ってしまう様な容量です。(この程度の計算をしてから質問しようね。) 上記を回答に代えて。 メモリの読み書きを、人が本のページをめくる早さだとすると、HDDの読み書きは、近所から宅配便(バイク便程度かなぁ(^o^))で送ってもらうようなもの(厳密には計算していません)。 それでも良ければ、「バイナリデータのファイル」を用意しても良いかと。 貴方の課題が速度について言及していませんが、蛇足まで。

lilillii
質問者

お礼

解答ありがとうございます。 メモリが厳しい環境を想定しているわけではないですが、 他の部分でのメモリ使用量もまだわかりませんし、 これから配列の大きさや数が増えるかもしれないので メモリを使わない方法がないかと思って質問しました。 今はこの程度の使用量なら宣言するのが一般的なんですね。 速度はそれほど気にしていませんが、バイナリでも変更 されてしまいそうなので、その方法は使わないことにしました。

  • ency
  • ベストアンサー率39% (93/238)
回答No.2

配列データとして、どこかに持っておかなければいけないわけですよね? それを、プログラムに組み込んでしまってメモリ上にすべて展開してしまうか、外部記憶に保存しておいて必要なものだけメモリ上に展開するのか、というお話で良いですよね? No1 boozer2005 さんが回答されているように、メモリサイズに余裕があるのであれば、そのままプログラム上に定義してしまって良いと思います。 もし、メモリサイズにあまり余裕がないような場合には、何らかの方法で外部記憶にデータを持たせて、必要な分だけ動的に領域を確保する、という方法にならざるを得ないと思います。 あと、そのデータが頻繁に更新されるような場合にも、その都度コンパイルを繰り返すことになるため、外部記憶にデータを持たせるべきでしょう。 さて、外部記憶にデータを持たせる方法ですけど、何もテキストファイルにする必要なないと思います。 たとえば配列イメージをそのままファイルに落とせば、バイナリファイルにしかならないでしょうし。 # ま、この場合、テキストエディタで開いた場合には見れないけど、 # バイナリエディタで開かれたら丸見えになってしまうんですけどね。 あとは、暗号化をしてファイルに保存するとかいう方法もあるでしょう。 簡単な方法としては、すべてのデータを 0xAAAAAAAA と XOR してからファイルに保存します。 そしてファイルから読み込んだ後は、そのデータをまた 0xAAAAAAAA と XOR をとれば、データは元に戻ります。 しかも、ファイルには全然別のデータが書き込まれることになります。 ちなみに、XOR をとるのは何でも良いです。 0x12345678 でも良いですし、0xDEADBEEF でもかまいません。 要は、同じ値で 2回 XOR すれば元の値に戻るので、それを使っているだけです。 # どうして、元に戻せるのかは、ちょっと考えてみてください。 こんなんで、参考になりますか?

lilillii
質問者

お礼

解答ありがとうございます。 なるほど、バイナリファイルに保持するのですか。 配列イメージをそのままというのがよくわからないのですが、バイナリエディタでも変更されてしまうのはまずいので 動的に宣言しようと思っています。

関連するQ&A

  • [arduino]数値の大きなデータを二次配列へ

    シリアル通信で得たデータを二次元配列へ格納するために、 以前では、 if(Serial.available()>120){ for(int k=0;k<8;k++){ for(int l=0;l<15;l++){ //読み込んだ値を配列に代入 matrix[k][l]=Serial.read(); } } } このようなやり方で読み込んだ値を二次元配列に代入していたのですが、 128個以上のデータを扱いたい場合、Serial.availableでは保持できず、困っています。 方法として、 (1)一つずつデータを読み込み、128回ループを繰り返し配列に貯めていく。その後配列を2次元配列に代入する。 (2)一つデータを読みこんだら二次元配列の1行目1列目のドットに格納、もう一つデータを読みこんだら二次元配列の1行目2列目のドットに格納…というように、 読みこんだデータをそのまま二次元配列のそれぞれの場所へ格納していく。 というような二つの方法を思いついたのですが、 (1)の方法では、配列にデータを貯蓄していくコードをこのように↓書いたのですがうまくいかず、 for(int i=0;i<128;i++){ if(Serial.available()>0){ data[128] = Serial.read(); } } (2)の方法では、データを二次元配列のそれぞれの場所へ格納していく指定方法が分かりませんでした。 正しい書き方や、良いアイデアをお持ちの方がいましたら、是非御教授お願いします。

  • 数配列の長さ

    あらかじめ決まってないint型の配列の長さはどうのようにして求めたら良いのでしょうか? int array[100];で宣言して実際に数字が入るのは100以下の様な状況 sizeofで調べると100になってしまうので配列の最後に@マークを代入して長さを調べてたのですが何か適切な方法はありますか? プログラミング初心者なのでこれ以上思いつかなかったので適切な方法があればよろしくお願いします。

  • 配列とポインタについて

    以下のような matrixの二次元配列の引数があるのですが、これを keisan2に渡す時にどのように記述すれば良いのでしょうか? ???部分が知りたいです。 また、char **matrixと matrix[][3]は違うものですか? 覚えるコツも知りたいです。 int keisan(int data, char matrix[][3]) { // 省略 return keisan2(dat, ???); } int keisan2(int data, char matrix[][3]) { // 省略 return 0; }

  • pythonの多次元配列へのデータ入力

    pythonの多次元配列で以下のように、ループのカウンタのn,mで配列の位置を指定して代入することができないようです。このような場合どう処理するのでしょうか。 for n in range(1:10) for m in range(1:10) a[n][m]=f(n/m) なお、aについては使用の宣言はしておらず、メモリも確保されていません。fは別途用意されています。 また、a[2][3]=1.3 のように配列の場所を指定して代入するのもダメのようです。numpy.arrayとかで宣言するのかなと思うのですが。使用例が見つかりません。2次元配列だけでなく3次元配列だとどうなるかなと思うのですが。 科学技術計算はこんなのばっかりです。pythonはそのようなものに向くでしょうか。いろんなものがpython対応になってきているので速さの問題があっても器用な処理ができるのなら選択されることも多いと思いますが。 よろしくお願いします。

  • 動的配列を宣言するためにnew演算子とdelete演算子を用いる方法が

    動的配列を宣言するためにnew演算子とdelete演算子を用いる方法があります。 2次元配列は以下のように宣言して作れるのは分かったのですが、 (実際に使って動かしてみました。) int **pp; pp = new int*[ROW]; // 行を作る for(int i = 0; i < ROW; i++) // 列を作る pp[i] = new int[COL]; http://www.asahi-net.or.jp/~uc3k-ymd/Lesson/Section02/section02_07.html(引用) 3次元配列をどのように作ったらいいか分かりません。 教えてください。宜しくお願いします。

  • 配列にないデータのみを代入する方法

    シェルスクリプトで重複するデータのない配列を作りたいのですが、配列に含まれていないデータのみを代入する、もしくは、代入したとしても配列内のデータの重複を取り除く方法を教えてください。 よろしくお願いいたします。

  • 配列の要素数を調べる方法

    配列の中にいくつ要素があるか後から調べる方法はあるでしょうか? int test[4][3] = {   {0,1,2},   {0,1,2},   {0,1,2},   {0,1,2}, } ; 上のケースだと、X方向に3、Y方向に4つの 要素があります。しかし、これだとあらかじめいくつ要素があるかを決めて 置かないといけません。 例えば、 int test[] = {0,1,2,3....} みたいに宣言された場合や、 char *test[] = {   "ああああああ",   "いいいいいい",   "うううううう",      ・      ・ //(これは文字列の数を要素数とします) } ; のように宣言された二次元配列などで、後から配列内にいくつ要素があるかを 調べることなどは可能でしょうか?

  • 多次元配列

    たとえば  int test[]={1,2,3}; のような場合は、配列の要素数を省略できます。 しかし、多次元配列の場合は左端の添え字しか省略できないのはなざでしょうか? 例  int test[][3]={{1,2,3},{4,5,6},{7,8,9}}; 全部省略できない理由がわかりません。 どなたか教えてれませんか?

  • Javaの配列の宣言方法のメリット?

    1週間ほど前からJavaを独学している者です。 C言語をその前からやっていて、初心者レベル程度ならわかると思います。 そこで、質問です。 C言語の配列宣言:   int array[10]; Javaの配列宣言:   int array[] = new int[10]; 二つの言語とも、要素10個のarray1次元配列変数を宣言していると思います。 C言語の書き方はシンプルなので、納得がいきますが、Javaの方はどうしてこの形で宣言をするのかわかりません。(自分が言語製作者ならシンプルな書き方を採用します) だから、このような宣言の方法をとるということは何か理由があるのだと思います。 自分が思うところ、JavaはC言語より、柔軟で多機能だとおもうので、その影響で汎用性をますために、 長くなっているのかな~?と思っています。 こんごJavaの学習を進めていくと、例えば、   int array[] = new double[10]; //←エラーになりました みたいに型のちがう、宣言が出てきたりするのでしょうか? ちらっと、学習に使っている本をみたところ、動的配列の作成は別の操作で実現しているようなので、 「動的とは関係ないのかな?」と思っています。 長くなりましたが、Javaの配列宣言のメリットを教えてください。

    • ベストアンサー
    • Java
  • 多次元配列への数値の代入。

    こんにちは。 今、多次元配列への数値の代入の仕方で、悩んでいます。 A[][] = new int[n][n]; B[][] = new int[n][n]; 上記のようなn行n列の配列を宣言し、nを入力します。 例えば、n=100と入力すると、100行100列の配列を定義したことになり、Aの配列には1~10000、Bの配列には10001~20000の数値を代入、200×200であれば1~40000、40001~80000…という感じにしたいのですが、いいアイディアが浮かびません。 また、1~nの間でランダムに数値を選び、その数値を代入というのも考えましたが、Javaで乱数を代入できるのかな?という疑問が出来てしまい、わからなくなってしまいました。 何かいい考えがありましたら、ぜひ教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう