Rogue Wave バナー
前へマニュアルの先頭へ目次索引次へ

9.3 プログラム例

この節では、3 つのプログラム例で mapmultimap の使用例を説明します。例として、電話データベース、グラフ、用語索引を扱います。

9.3.1 例: 電話番号のデータベース


注: 完全なプログラム例は、tele.cpp チュートリアルファイルにあります。

単純な電話番号のデータベースのプログラムの保守は、map に適した用途です。データベースは単純にインデックス付けされた構造で、人名や職業 (string) がキー値であり、電話番号 (long) が関連付けられたエントリです。このようなクラスは、以下のように書きます。

データベースでの単純な演算は、map コマンドによって直接的に実装されます。データベースへの要素の追加には insert、要素の削除には erase を使用し、更新にはこの 2 つを組み合わせて使用します。データベースのすべてのエントリを印刷するには、for_each() アルゴリズムを使用し、次の単純なユーティリティルーチンを各エントリに適用します。

次に、第 13 章で説明する、map で使用できるいくつかのアルゴリズムの使用方法を説明するために、少し複雑な演算の組み合わせを使用します。特定の 3 桁の初期接頭辞 1 が付いたすべての電話番号を表示するとします。クラス mapfind() メンバー関数と混同しないように、find_if() 関数を使用し、最初のエントリを検出します。この位置から開始して、次に find_if() を呼び出すと、エントリが連続して表示されます。

この演算の述語には、データベースのエントリを示す pair という 1 つの引数だけを使用するブール型の関数が必要で、これは指定された接頭辞であるかどうかを示します。これに明らかに適した関数はなく、テスト接頭辞が引数として比較関数に渡されることはありません。この問題の解決策は、一般的な標準 C++ ライブラリ手法を適用することです。すなわち、クラスのインスタンスとして述語関数を定義し、クラスが作成されると初期化されるクラスのインスタンス変数としてテスト述語を格納します。目的の関数は、関数を呼び出すクラスの演算子として定義されます。

最後の例では、接頭辞によってソートされたディレクトリを表示します。map 自体の順序を変更することはできません。代わりに、逆の要素型の新しい map を作成し、値を新しい map へコピーすると、接頭辞によって値が順序付けられます。新しい map が作成されると出力されます。

以下は、ソートされたエントリーの印刷に使用される関数です。

9.3.2 例: グラフ


注: このプログラムの実行可能バージョンは、graph.cpp ファイルにあります。

各要素自体が map である map は、指定されたグラフの自然な表現です。たとえば、都市名を符号化する文字列を使用して、エッジに関連付けられた値を、2 つの都市間の距離とする map を作成するとします。このグラフは、以下のように作成することができます。

stringVector 型は、string によってインデックス付けされた integer の map です。graph 型は、実質的に 2 次元の疎配列で、strings によってインデックス付けされ、integer 値を保持します。代入文のシーケンスは、グラフを初期化します。

多数の古典的なアルゴリズムを使用して、この形式で表現されるグラフを操作することが可能です。その一例に、ダイクストラ (Dijkstra) の最短経路アルゴリズムがあります。ダイクストラのアルゴリズムは、初期地点として指定された特定の都市から開始します。距離/都市の priority queuepair が作成され、開始都市からの距離で初期化されます (すなわち、0)。距離の pair のデータ型の定義は、次のとおりです。

次のアルゴリズムでは、各ステップで、最大ではなく最小の値をコレクションから引き出そうとするため、条件付きテストが priority queue で逆になることに注意してください。ループの反復のたびに、queue から都市を引き出します。都市への最短経路が見つからない場合は、現在の距離が記録され、グラフを検証することによって、この都市から隣接する各都市への距離を計算することができます。この処理は、priority queue がすべて処理されるまで続きます。

これは vectormapstringpriority queue を使用する比較的単純なアルゴリズムであることに注意してください (第 11 章)。

9.3.3 例: 用語索引

用語索引は、各語句が発生する行番号を示すテキスト内の語句の、アルファベット順一覧です。

用語索引は map および multimap のコンテナクラスの使用を示すために開発されたものです。データ値は multimap による用語索引で維持され、string (語句) でインデックス付けされ、integer (行番号) を保持します。同じ語句が複数の異なる行に表示されることがあるため、multimap が適用されます。事実、このような関係を見つけ出すことが、用語索引の主要な目的の 1 つです。もう 1 つの map 使用の可能性は、関連付けられた値として整数要素の set を使用することです。

用語索引の作成は 2 つのステップに分けられます。すなわち、プログラムが入力ストリームから行を読み取って用語索引を生成するステップと、結果を出力ストリームに出力するステップです。これは、2 つのメンバー関数 readText()printConcordance() に反映されます。1 つ目は readText() で、次のように書かれます。

行は 1 行ごとに入力ストリームから読み取られます。まず、行のテキストが小文字に変換され、次に 12.3 節 に記述されている関数 split() を使用して行が語句に分割されます。各語句は用語索引に入力されます。用語索引への値の入力に使用されるメソッドは、次のとおりです。

addWord() の大部分は、1 行に同じ語句が 2 回発生する場合、値が語句 map で重複しないようにするために費やされます。これを確実にするために、キーと一致する値の範囲が検証され、各値がテストされた結果、一致する行番号がない場合は挿入が実行されません。行番号が検出されることなくループが終了した場合に限り、新しい語句/行番号の組み合わせが挿入されます。

最後のステップは用語索引の出力です。これは、次のように実行されます。

反復子ループは、語句一覧で維持される要素の循環に使用されます。新しい語句ごとに新しい出力行が生成され、その後、空白で区切られた行番号が表示されます。たとえば、入力がテキストの場合は以下のようになります。

It was the best of times,

it was the worst of times.

best から worst までの出力は次のようになります。
best:
1
it:
1 2
of:
1 2
the:
1 2
times:
1 2
was:
1 2
worst:
1



前へマニュアルの先頭へ目次索引次へ
Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月