- ベストアンサー
配列入れ替えの効率的方法は
VBでグローバル変数配列を3000とっています。 格納されているデータを、1つづつずらして代入し直しをやりたいのですが 配列添え字1のデータを配列添え字0にというふうに3000回のループで 処理する以外に良い方法はないでしょうか 例 for i=0 to 2999 a[i]=a[i+1]
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
>次に発生するデータを配列に追加する処理を考えていたので発生するデータが1個であれば1つずらして空きをつくりそこに代入しようと考えていました。 それならやはりリングバッファが目的にかなっているではないですか。 X = (X + 1) Mod 3000 '最初の添え字は最後になる a(X) = NewData '最初にデータを追加 Debug.Print a(X + n) 'n番目のデータを表示する こういうのがアルゴリズムというものです。 ちなみに、"補足" を利用した場合、1つのところに書くとすべての回答者にメールが行くので、同じことを書く必要はありません。
その他の回答 (6)
- imogasi
- ベストアンサー率27% (4737/17069)
本質問の解答にはならないかもしれませんが、有名な「リングバッファー」というデータ構造について、読んで考えて見られては。何かの参考になるかも知れない。 http://www5c.biglobe.ne.jp/~ecb/c/14_06.html など、リングバッファーでWEB検索する。また「データ構造」の教科書などを見る。Javaでは、この名のクラスも あります。 本質問は(可能なら)配列(ファイルレコード?)の後ろの方から逆読みをして、自分の土俵の配列の後ろへ追加していけば、元ファイルと同じ順になり処理スタートとしてはそれで良いのではないのでしょうか。
- imogasi
- ベストアンサー率27% (4737/17069)
#3のものです。 >リアルタイム処理で・・・ リアルタイム処理かどうかの問題は関係無いと思います。 >1個であれば1つずらして空きをつくりそこに代入しようと・・・ 普通は配列には後ろ(使用配列要素数が最大の次に)にデータを追加する ものではないでしょうか。 それに対し本件では第1要素a(1)に追加しなければならない理由こそ明らかにすべきだと思います。その必然性を解答者が納得すれば、答えも最適なものが出やすいと思います。
補足
質問が不備で大変御迷惑お掛けしました。 ややこしい文になってしまわないかと心配して簡略になってしまいました。 具体的には、以下のようなことをやろうとしていました。 Aテーブルに日付と座標データが一定時間毎にレコードが作成されていきMAX3000レコードになったら一番古いレコードが削除されて新しい日付と座標データが一番最後に追加される処理が別で動いています。 そのAテーブルからデータを読み出して、配列に格納してグラフ表示をさせるのが目的です。データレコードが自動で更新されているので、その都度最初から読み直せば良いと思うのですが、追加されたデータだけを読んで配列に追加できないかな? と考えていました。(既に読み込んでいるデータを再度読まなくても済むように) 追加する配列要素は最大の次です。ちなみにSQLで読み込みます
- haporun
- ベストアンサー率40% (230/562)
C的な考え方ですが、インデックス何番目が、扱うときの0番目であるかをメモればいいのではないでしょうか? 適当な変数Xに最初の要素の番号を入れるのです。 アクセスするときは常に((X+n) Mod 3000)でアクセスします。 そうすれば、データを移動することなく、データの番号をずらすことができます。 データ移動後のアクセスがあまりに多い場合は、アクセス時の計算量が増えるので、効率が良いかどうかは微妙です。 しかし、アクセス数が3000回に満たないなら、この方法はお得です。
お礼
有難うございました。 リングバッファを見てみました。 こうゆう考え方があるのですね、とても勉強になりました。
補足
早速のお返事有難うございました。 説明不足で申し訳ございません。 リアルタイム処理で次に発生するデータを配列に追加する処理を考えていたので発生するデータが1個であれば1つずらして空きをつくりそこに代入しようと 考えていました。
- imogasi
- ベストアンサー率27% (4737/17069)
配列要素3000と言えば(メモリーが少なかった)昔なら相当なレコード量で、配列に持つなど考えられなっかたです。 もう線形で持つのは止めて、適当な「構造」を配列部分に持ちこむべきではないでしょうか。例えばHeap,Treeなど。 なぜ「ずらす」必要があるのか。まず考えついたロジックで安易にやって居ないか考えて見るべきで、その最適ロジックが無いかこそ質問すべきことではないのでしょうか。見当外れだとお許し下さい。 それと、「ずらしたい」ときは最後の方からやらないとダメでは。 × for i=0 to 2999 a[i]=a[i+1] ○ For i=2999 to 0 Step -1 a(i+1)=a(i) Next i
お礼
有難うございました。 ロジックの考え方が悪いのでしょうね? データの追加は、配列要素の最大値に入れますので 配列要素の最大値に空きを作ります。 ずらす方法は、最大値から行なうのですね 大変勉強になりました。
補足
早速のお返事有難うございました。 説明不足で申し訳ございません。 リアルタイム処理で次に発生するデータを配列に追加する処理を考えていたので発生するデータが1個であれば1つずらして空きをつくりそこに代入しようと 考えていました。
- sha-girl
- ベストアンサー率52% (430/816)
処理速度についての問題でしょうか? だとするとソートプログラムでもない限り 配列を入れ替えるというのは無駄なように思います。 配列を読む方でiの値を動かす方がいいでしょう。 特にVB6ではそういった単調作業が苦手のようです。 VCで作ったDLLにでも配列を渡せば、3000個程度の long型であれば瞬時ですけどね。
お礼
有難うございました。 Dosの頃にcはやったことがありましたが VBは未だ初心者です
補足
早速のお返事有難うございました。 説明不足で申し訳ございません。 リアルタイム処理で次に発生するデータを配列に追加する処理を考えていたので発生するデータが1個であれば1つずらして空きをつくりそこに代入しようと 考えていました。
- maruru01
- ベストアンサー率51% (1179/2272)
こんにちは。maruru01です。 コレクションを使う方法があります。 使用方法はすでにご存知かも知れませんが、 Dim myCollection As New Collection と宣言して、 myCollection.Add Item:=a とコレクションに追加していきます。 追加した順に1からインデックスがつきます。 そして不要なデータを、 myCollection.Remove i (iはインデックス番号) と削除すると、削除された分インデックスが前に詰められます。 ただし、追加順が不定の場合はそのまま使えないので、とりあえず配列に入れておいて、全部入れた後で、 For i = 1 To 3000 myCollection.Add Item:=Hairetu(i - 1) Next i と、まとめて追加するか、 For i = 1 To 3000 myCollection.Add Item:="" Next i みたいに、ダミーデータで追加しておいて、 myCollection(100) = "a" などと中身を後で代入するかです。
お礼
補足で大変御迷惑をお掛けしました。 コレクションコントロールでは、 少し使ったことがありますが未だ勉強不足です 有難うございました
補足
早速のお返事有難うございました。 説明不足で申し訳ございません。 リアルタイム処理で次に発生するデータを配列に追加する処理を考えていたので発生するデータが1個であれば1つずらして空きをつくりそこに代入しようと 考えていました。
お礼
VBが初心者で申し訳ございませんでした。 リングバッファというものが知りませんでしたので 調べてみます。 有難うございました。