• ベストアンサー

VBでリスト構造を実現するには?

DTDとHTMLのパーサを作ろうと思い、データを解析して配列に入れようとしていたのですが、配列じゃなくてリスト構造で実現しろというお達しをうけて非常に困っています。 そもそもVBでリスト構造って実現できるんでしょうか?実現できるのであればその方法を教えていただきたいと思っています。

  • runo1
  • お礼率22% (2/9)

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

  • ベストアンサー
  • ARC
  • ベストアンサー率46% (643/1383)
回答No.7

>1:一度未使用リストに追加するという段階を踏むのはどうしてでしょうか? Cでやるように、簡単にメモリの開放が行えないからです。 配列を使ったリスト構造ですので、リストから削除する操作を行った場合でも、削除された要素はまだ配列の中に含まれます。 その後、リストに再度、追加操作を行ったときには、出来れば先ほど削除した要素を再利用したいですよね。 未使用リストを使わない場合でしたら、配列のどの要素が今は使われていて、どの要素が既に開放されているのかを知るのが難しくなります。 配列に削除フラグを持たすっていうパターンも考えられますが、その場合は、最初の削除済み要素が見つかるまで、配列の始点から順々に、ずずーーっと探していかなくてはなりません。 それに対して、空き要素も同じくリスト構造にしておけば、削除済みフラグも要りませんし、空き要素の探索も、先の例のようにすごくシンプルに実装できます。 >2:この配列の方法以外でもいいのですが、リスト構造の中に更にリスト構造を作る方法ってあるでしょうか? リスト構造をクラスの形で作成します。 クラス名を「CDolbyList」とでもして、 Add Remove MoveNext などもメソッドを実装してやります。 クラスの内部でデータを保持する構造体の方は Type typHoge   sData  as Valiant   lPrev  as Long   lNext  as Long End Type ってな感じですね。 あとは、 CDolbyListをNewして、別のCDolbyListにAddしてやればいいです。 もしくは、親リストと子リストを別々のクラスにして、 親リストの構造体の方を Type typHoge   sData  as C子リスト   lPrev  as Long   lNext  as Long End Type ってな感じで作ってやってもいいかもしれませんね。 (多分こっちの方がパフォーマンスは良くなる。)

runo1
質問者

お礼

PCが壊れて、しばらくネットに接続できない状態だったのですが、ようやく修理から戻ってきました。お返事遅れて申し訳ありません。 本当に丁寧なご回答どうもありがとうございました。 VBについてはほとんどなにもわからない私でも、わかりやすく説明していただいたおかげでなんとか目処がたつかな、という気になってきました。 がんばってVBを使ってみようと思います。

その他の回答 (6)

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.6

1:>Hoge(2)のNextを見ます。EOF(つまり3)であれば というのは「未使用リストのBOFを見る」という意味合いの処理でしょうか? 未使用リストのBOF(Before Of File)の次の要素がEOF(End Of File)かどうかを調べるっていうことです。 頭の直後が尻尾なら、胴体が空っぽ… (汗 IF Hoge(2).Next = 3 then   配列を拡張して、未使用リストにデータを追加してやります。 END IF >というのは、追加されるもの自体が末尾になるのではなくて、末尾の一つ前の要素になるということ? そういうことです。 実際のデータは、必ずBOF(頭)とEOF(尻尾)の間に存在します。 このような構造にしていると、様々なメリットが得られます。 まず、MoveNextとか、MovePreviousとかの処理を実装する際、一々その先頭/末尾かどうかのチェックをしなくてすみます。 それから、カレントレコードがEOFか否かを示すプロパティ*1を一つつけ加えるだけで、呼び出し元から以下のような感じでロジックが組めるようになります。 List.MoveFirst 'カレントレコードをHoge(0).Nextが示す場所に設定する。 Do Until List.EOF   処理を記述   List.MoveNext 'カレントレコードをカレントレコード.Nextが示す場所に設定する。 Loop *1 Property Get EOF() As Boolean   EOF=(カレントレコード=1) End Property ってな感じです。 どうです?イメージがつかめましたか?

runo1
質問者

補足

回答、ありがとうございます! ええと、カレントレコードがEOFになるまでループ、その間中はカレントレコードに対し処理を行い、カレントレコードを1進めるということですよね。 最初、Do~以降の処理が、MoveFirstメソッドの実装をしているものだと勘違いしてしまい、10分ほど思いっきり悩んでしまいました(笑) 確かにそういう約束事(BOFとEOFの間に実際のデータがある)というのがあると処理がすごく綺麗になりますね。 ええと、もう二点ほどよろしいでしょうか。 1:一度未使用リストに追加するという段階を踏むのはどうしてでしょうか? 「ここがミソ」のはずなのに、全然わかってません・・・・・・(汗) 2:この配列の方法以外でもいいのですが、リスト構造の中に更にリスト構造を作る方法ってあるでしょうか? HTMLのツリー構造をサーチする順番などを考えているうちに、リスト構造の中にリスト構造が作れればだいぶ楽になりそうだという風に思ったので・・・・・・。

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.5

ちゃい。 × 1:Hoge(3)のNextを見ます。EOFであれば、 ○ 1:Hoge(2)のNextを見ます。EOF(つまり「3」)であれば、 でした~

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.4

続きです。 その2に関しては、むか~し、遊びで作ったことがありますので、そのときのやり方を紹介します。 双方向の線形リストの例です。 まず、最初に配列に4要素を追加します。 'リストの先頭(BOF)です。 Hoge(0).Prev=-2147483648# Hoge(0).Next=1 'リストの末尾(EOF)です。 Hoge(1).Prev=0 Hoge(1).Next=2147483647 '未使用リストのBOF Hoge(2).Prev=-2147483648# Hoge(2).Next=3 '未使用リストのEOF Hoge(3).Prev=2 Hoge(3).Next=2147483647 つまり、一つの配列の中に二つのリスト構造が同居しているわけです。(ここがミソ) 配列にデータを追加するときは、未使用リストから1要素減らし、それをリストに挿入します。 リストからデータを削除するときは、リストから一要素減らし、それを未使用リストに追加します。 追加処理(概要だけ) 1:Hoge(3)のNextを見ます。EOFであれば、配列を適当な数だけ拡張します。増えた分の要素は未使用リストに追加します。 2:未使用リストから一要素削除し、リストに挿入します。リストの末尾に追加するのでしたら、Hoge(1)と、Hoge(1).Prevの間に挟み込めばいいんですね。 削除処理とかは、適当にアレンジして作ってくださいね(横着 ちなみに削除しても空白リストの要素数が増えるだけでメモリ開放はされないので、必要であればガベージコレクションして、Redimして、メモリを開放してください。

runo1
質問者

補足

ご丁寧な回答、ありがとうございます。 その親切心に甘えさせていただいて頂くようで悪いのですが、二点ほど確認させていただいてよろしいでしょうか? 1:>Hoge(2)のNextを見ます。EOF(つまり3)であれば というのは「未使用リストのBOFを見る」という意味合いの処理でしょうか? 2:>リストの末尾に追加するのでしたら、Hoge(1)と、Hoge(1).Prevの間に挟み込めばいいんですね。 というのは、追加されるもの自体が末尾になるのではなくて、末尾の一つ前の要素になるということ? VBについては実はまったく素人なもので(笑)、馬鹿なことを聞いているようでしたら笑って聞き流してください。

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.3

その1。コレクションオブジェクトを使う。楽チンです。内部的にもリスト構造になっています。 その2。動的配列を使う。 VBではポインタは使えませんので、配列の添え字をポインタの代わりに使います。 Type typHoge   sData  as String   lPrev  as Long   lNext  as Long End Type Dim Hoge() as typHoge などとして、lPrev,lNextには配列の添え字を入れます。 配列を増やすときは、Redim Preserve ね。 クラスにしてAddやRemoveといった要素を追加してやります。 その3。非接続型のADOを使う。慣れればこっちの方が手っ取り早いかも。機能も豊富だし。 ただしちょっと複雑だし、プロジェクトによってはADO使っちゃダメってな場合も。 Dim rsHoge As New ADODB.Recordset() Dim Fld As ADODB.Field Dim sSQL As String rsHoge.Fields.Append("DATA", ADODB.DataTypeEnum.adBSTR) rsHoge.Open() rsHoge.AddNew() rsHoge.Fields("DATA").Value = "hoge" rsHoge.Update() rsHoge.AddNew() rsHoge.Fields("Data").Value = "moga" rsHoge.Update() rsHoge.MoveFirst() MsgBox(rsHoge.RecordCount & ", " & rsHoge.Fields("Data").Value)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

上役?がいう「リスト構造で実現しろ」は(1)一方向リストか(2)双方向リスト(木構造)なのか良く考える必要があります。 木構造について http://www5c.biglobe.ne.jp/~ecb/c/14_08.html ズバリを話題にしたものとして http://pascal.cs.kobe-u.ac.jp/~shii/win/etc/VbList.html http://www.alpha-net.ne.jp/users2/ei9711/vbkouza/kouza16.html 例題はC言語ですが、解説として http://www.cs.shinshu-u.ac.jp/Lecture/SE2/2000/L5-2.html など。

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.1

ぬぉ

参考URL:
http://pascal.cs.kobe-u.ac.jp/~shii/win/etc/VbList.html

関連するQ&A

  • リスト構造について

    C++言語で住所録を作ろうとしていますが、今回始めてポインタを使ったリスト構造を使ってみるこ とにしました。 そこでふと思ったのですが、VBではポインタなど無いと思ったのですが、このような場合はどうやって リスト構造を実現するのですか? VBは昔触ったことが有りますが、今は触っていません。 イメージが分かる程度の回答で結構です。

  • VB6でやると構造体の配列になる変数をVB2008では何で作ればいいか

    VB6でプログラムを作っていたときは 値のセットが配列になるとき 構造体を動的配列で宣言してデータを足して作りました。 VB2008で開発をすることになり 同じようなことをしたいのですが もっと便利なやり方が登場したりするのでしょうか? クラスで挑戦したのですが動的配列はできないようでした。

  • リストボックスにリストを設定

    リストボックスにリストを設定 VB2005,XP です。 配列a(3,10)という配列があったとします。 この配列の(0,0~10)の値をリストに設定(バインド)したり、 構造体b(10) b().NO b().Name b().scale ・・・・ のb.Nameをリストに設定(バインド)する方法を 教えてください。 よろしくお願いします。

  • HTML::Parserの解析結果

    HTML::Parserを使ってHTMLからimgタグを抽出しようとしています。 http://homepage3.nifty.com/hippo2000/perltips/html/Parser.htm などの解説どおりに書けばimgタグの各項目を取り出すことは出来るのですが結果を配列で取得することができません。 解析したいHTMLを渡すことでimgタグの各情報を配列で受け取るには堂書けばいいのか教えてください。 HTML::TokeParserも試してみましたがまれに正しく抽出できない場合があり使えませんでした。 同じHTMLをHTML::Parserで解析したところ全て正しく抽出できたのでHTML::Parserで処理したいと考えています。

  • VB6のListの使い方

    VB6でListを使っています。 最初、Listに複数のデータが入っています。 何かデータを取得したら、、Listの該当するところのデータを変えていきたいのですが、できますか? Additemで項目の追加はしたことがありますが、変更の仕方が分かりません。 ただし、最初にあるデータはそのままで変わったところだけ変更していきたいです。

  • リスト構造

    リスト構造がポインタを使って繋ぐ、という事はわかったのですが、例えば電話帳を作るとして、入力、保存、検索、のコマンドを作っても一度プログラムを終了するとデータは消えてしまいますよね?ファイルに保存したとしても、次に見るときにはまた、リスト構造にこれらのデータを戻すのですか?? よくわからないので教えて下さい。お願いします。

  • リスト構造

    リスト構造の問題なんですが リスト構造を使ってファイルに読み込み、書き込み データの追加、一覧表示、削除といった機能を持ったプログラムを 作成しなければいけないのですがリストをつなげたり切り離したり することができません ポインタを使うところまでは分かるのですがリストをつなげたり切り離したりする部分がよく分かりません どうすればよいのでしょうか どなたか回答お願いします

  • C++: HTMLパーサを探しています。

    C++のHTMLパーサライブラリを御存じの方がおられましたら、教えて頂けませんでしょうか。 XMLパーサはちらほら見つかるのですが、HTMLの解析ができるものを探しております。 PerlモジュールのHTML::TreeBuilderのようなtree構造の解析までできるものが理想です。 宜しくお願いいたします。

  • VB2005 ExpressEditionで勉強しています。

    VB2005 ExpressEditionで勉強しています。 カンマ区切りの文字列を一旦配列に入れて配列のデータを ひとつずつリストボックスに入れる処理を作っているのですが、 配列に重複したデータがあるのでそれをひとつにしたいです。 配列にデータが入ってる時か、リストボックスに入れるときのどちらかで やりたいです。いい方法を教えてください。 本などで探したのですが見つかりません。 イメージは、配列が (aaa,bbb,ccc,aaa)だとすると リストボックスに入るときに (aaa,bbb,ccc)になっていればいいです。

  • 構造体リストの使い方について

    こんにちは。 断片データを受取ってから一旦復帰し、再びデータが送られ、全てのデータを受取った後に今まで受取った断片データを全てソートしたものを返却する関数を作成しようとしています。  断片データを保存する際には、動的に構造体領域を確保して実現しようと考えています。 まず、受け渡されるデータの形式は以下のようなものです。 グループA{A1,A2,A3…要素の数は可変} グループB{B1,B2,B3…要素の数は可変} グループC{C1,C2,C3…要素の数は可変} : グループの数は可変 ※グループの数と要素の数は、実際に受け渡されたデータの中身を見ないと分からない。 受け側では、まず 1.グループは新規グループか? を判定する。  ・新規グループなら、新規要素分の領域を動的確保し、新規構造体リストへ登録する。  ・既存グループなら、新規要素分の領域を動的確保し、対象となる構造体リストへリンクする。 2.グループの要素を全て受取ったら  ・構造体リスト内のデータをソートし、リンクを張りなおす。 上記1.2処理を、グループ全てを受取るまで繰り返す。 [質問内容] 1.グループが1つの場合は、1つの構造体を自己参照構造体にし、受け渡されるデータを次々と動的領域確保及び設定にて実現できそうなんですが、グループの数が可変のため、どう制御すればよいのか分かりません。仮に、グループ全体を管理するテーブル領域のようなものを用意し新規グループが発生するたびに、管理テーブルへ登録するというようなやり方は問題ないのでしょうか。また問題ない場合は、管理テーブルで可変領域を確保するにはどうすればよいのでしょう か。 2.1つの構造体リスト内をソートするアルゴリズムを記載したサイトなどありましたら、教えてください。 以上、説明不足のところもあるかもしれませんが、よろしくお願いします。

専門家に質問してみよう