[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/08/02(Tue) 19:30
投稿者名:chama
Eメール:
URL :
タイトル:
配列の大きさを減らしたい
こんにちは。教えていただきたいことがあります。

A(A_MAX)とB(B_MAX)という配列があり、Bと等しいAの要素を選択したいと考えてます。
ここで、A,Bの両配列とも各々で重複した値はないとします。

例:A(1)=3,A(2)=1,A(3)=2
  B(1)=5,B(2)=3,B(3)=2,B(4)=4,B(5)=1
  ※A(1)はいずれのA(j)とも重複しない。A(1)≠A(j)

ごく単純に、
for i= 1 to B_MAX
   for j= 1 to A_MAX
      if(A(j) = B(i))then
         ・A(j)の格納操作
         exit for
       endif
   next j
next i
としました。

A,Bの両配列とも大きさが10,000程度あるので、めちゃくちゃ処理時間がかかってしまいます。
そのため、一度ヒットしたB(i)を比較対象から外したいと考えてます。
つまり、
1.A(1)と等しいB(i)を見つけるループ → 全てのB(i)を対象として見つける(B(2)がヒット)
2.A(2)と等しいB(i)を見つけるループ → B(2)を除去したB(i)を対象として見つける
というようにしたいのですが、配列の大きさを小さくする方法が分からず、困ってます。

動的配列では配列の大きさを大きくすることはできても、小さくできないと書いてありました。
ほかに方法はないのでしょうか。

ご教示のほどお願いいたします。

投稿時間:2005/08/02(Tue) 19:43
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 配列の大きさを減らしたい
> 動的配列では配列の大きさを大きくすることはできても、小さくできないと書いてありました。
ヘルプの下記の部分ですか?
同様に、キーワード Preserve を使用した場合、動的配列のサイズを変更するために変え
られるのは、添字の上限だけです。添字の下限を変更しようとすると、エラーが発生します。

この場合の添字の下限とは、ReDim Preserve a(1 to 10) のような 1 の値(下限)
を意味しており、a(10) の 10は上限になります。

ヘルプを見て解釈されたのだと思いますが、簡単な事なので試して見る事ですね。
(ヘルプが間違っている場合も結構ありますし)

下記を試して見て下さい。
Private Sub Command1_Click()
    Dim a() As Integer
    Dim i As Long
    
    ReDim a(100)
    For i = 0 To 100
        a(i) = i
    Next i
    ReDim Preserve a(10)
    For i = 0 To 10
        Debug.Print a(i)
    Next i
'   ReDim Preserve a(1 To 10) ' 従ってこれはNG
End Sub


Private Sub Command1_Click()
    Dim a() As Integer
    Dim i As Long
    
    ReDim a(100, 10, 10)
    For i = 0 To 10
        a(1, 1, i) = i
    Next i
    ReDim Preserve a(100, 10, 5)
    For i = 0 To 5
        Debug.Print a(1, 1, i)
    Next i
End Sub

投稿時間:2005/08/03(Wed) 10:57
投稿者名:chama
Eメール:
URL :
タイトル:
Re^2: 配列の大きさを減らしたい
ありがとうございます。
下限の意味を間違えてました。

私は、配列の最大値(上限と分かりました)を減らすことを下限は変更できないって
解釈していました。
ちなみに、配列の真ん中辺りのデータを削除して、配列の大きさを詰める作業は、
自分でいちいち定義してあげないとだめでしょうか。



> > 動的配列では配列の大きさを大きくすることはできても、小さくできないと書いてありまし
た。
> ヘルプの下記の部分ですか?
> 同様に、キーワード Preserve を使用した場合、動的配列のサイズを変更するために変え
> られるのは、添字の上限だけです。添字の下限を変更しようとすると、エラーが発生します。
>
> この場合の添字の下限とは、ReDim Preserve a(1 to 10) のような 1 の値(下限)
> を意味しており、a(10) の 10は上限になります。
>
> ヘルプを見て解釈されたのだと思いますが、簡単な事なので試して見る事ですね。
> (ヘルプが間違っている場合も結構ありますし)
>
> 下記を試して見て下さい。
> Private Sub Command1_Click()
>     Dim a() As Integer
>     Dim i As Long
>    
>     ReDim a(100)
>     For i = 0 To 100
>         a(i) = i
>     Next i
>     ReDim Preserve a(10)
>     For i = 0 To 10
>         Debug.Print a(i)
>     Next i
>  '   ReDim Preserve a(1 To 10) ' 従ってこれはNG
> End Sub
>
>
> Private Sub Command1_Click()
>     Dim a() As Integer
>     Dim i As Long
>    
>     ReDim a(100, 10, 10)
>     For i = 0 To 10
>         a(1, 1, i) = i
>     Next i
>     ReDim Preserve a(100, 10, 5)
>     For i = 0 To 5
>         Debug.Print a(1, 1, i)
>     Next i
> End Sub

投稿時間:2005/08/03(Wed) 11:53
投稿者名:じゃんぬねっと
Eメール:
URL :http://jeanne.wankuma.com/
タイトル:
Re^3: 配列の大きさを減らしたい
> ちなみに、配列の真ん中辺りのデータを削除して、配列の大きさを詰める作業は、
> 自分でいちいち定義してあげないとだめでしょうか。

そういうメソッド (関数) を創れば、そんなに面倒なことではありません。

投稿時間:2005/08/03(Wed) 12:39
投稿者名:エデン
URL :
タイトル:
Re^3: 配列の大きさを減らしたい
> ちなみに、配列の真ん中辺りのデータを削除して、配列の大きさを詰める作業は、
> 自分でいちいち定義してあげないとだめでしょうか。

削除したいデータと配列の末尾のデータを入れ替えてからRedimすれば、詰める処理は不要では?
配列データの並び順に意味があるのならダメですけど。

投稿時間:2005/08/03(Wed) 12:29
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re: 配列の大きさを減らしたい
> ほかに方法はないのでしょうか。

 Bを高速なアルゴリズムを使用してソートし配列Cを作成する。検索するときは、
Cをバイナリサーチで検索する。というやり方のほうが早いのではないでしょうか。

 もしも、A,Bの配列のとる値が、整数値で、かつ、ある程度の範囲(MAX値分の
配列がとれる)内であれば、値とインデックスを逆にしたテーブルを作れば、
超高速に処理できると思います。

 たとえば、

 B(1)=5,B(2)=3,B(3)=2,B(4)=4,B(5)=1

 なら

 C(1)=5,C(2)=3,C(3)=2,C(4)=4,C(5)=1

 あれ、例が悪すぎ。Bとおんなじになってしまいましたので、例を変えます。

 B(1)=3,B(2)=8,B(3)=5,B(4)=4,B(5)=1

 なら

 C(1)=5,C(2)=0,C(3)=1,C(4)=4,C(5)=3,C(6)=0,C(7)=0,C(8)=2

 こんな配列を作成しておけば、A(1)=3と等しいB(i)は、C(3)=1より
B(1)ということがすぐにわかります。