C ++ STLレビュー(13)コンテナーアダプター

STLは、スタックスタックアダプタ、キューアダプタ、priority_queue優先キューアダプタの3種類のコンテナアダプタを提供します。
ここに画像の説明を挿入
さまざまなシナリオでは、さまざまな順次コンテナーが下部でさまざまなデータ構造を使用するため、コンテナーアダプターの実行効率も異なります。

1スタック

スタックアダプタは、シングルエンドの開口部を持つコンテナです。実際、コンテナはスタックストレージ構造をシミュレートします。つまり、データを格納する場合でも、データをフェッチする場合でも、操作はこの開口部からのみ実装できます。
ここに画像の説明を挿入
スタックアダプタの先頭は通常、スタックの最上位と呼ばれます。データの保存と取得はスタックの最上位からのみ実行できるため、データにアクセスするために、スタックアダプターには、アダプターの最上位の要素のみにアクセスでき、スタックの最上位の要素のみにアクセスできるという機能があります。その後、スタック内の要素にアクセスできます。
スタックに格納されている要素は「後入れ先出し(LIFO)」ルールを満たし、スタックアダプタもこのルールに従います。

1スタックコンテナアダプタの作成

スタックアダプタは、テンプレートクラスstack <T、Container = deque>(Tはストレージ要素のタイプ、Containerは基になるコンテナのタイプを表す)の形式でヘッダーファイルに配置され、で定義されているためです。 std名前空間。したがって、コンテナを作成する前に、プログラムに次の2行のコードを含める必要があります。

#include <stack>
using namespace std;

1

要素を含まないスタックアダプタを作成し、デフォルトのdequeベースコンテナを使用します。

std::stack<int> values; 

上記のコード行は、格納可能なint型要素を正常に作成し、最下層はdequeベースコンテナーのスタックアダプターを使用します。

2

上記のように、stack <T、Container = deque>テンプレートクラスは2つのパラメーターを提供します。2番目のテンプレートタイプパラメーターを指定することにより、コンテナーがempty()をサポートしている限り、dequeコンテナー以外の他の順次コンテナーを使用できます。 size()、back()、push_back()、pop_back()の5つのメンバー関数で十分です。
アダプターを紹介するときに、シリアルコンテナーにはこれらの5つのメンバー関数が同時に含まれていると述べられました。コンテナーには、vector、deque、listの3つがあります。したがって、スタックアダプタのベースコンテナはそれらのいずれでもかまいません。たとえば、リストベースコンテナを使用するスタックアダプタを定義する方法を次に示します。

std::stack<std::string, std::list<int>> values;

3

コンテナーのタイプがスタックの最下部で使用される基本コンテナーと同じである限り、基本コンテナーを使用してスタックアダプターを初期化できます。例えば:

std::list<int> values {
    
    1, 2, 3};
std::stack<int,std::list<int>> my_stack(values);

初期化後のmy_stackアダプターでは、スタックの最上位要素は1ではなく3であることに注意してください。さらに、コードの2行目で、スタックの2番目のテンプレートパラメーターをリストとして明示的に指定する必要があります(int型で、ストレージタイプと一致している必要があります)。そうでない場合、スタックの最下層は両端キューコンテナーを使用します。デフォルトでは、lsitコンテナのコンテンツは使用できません。スタックアダプタを初期化するため。

4

スタックアダプタを使用して、それらが格納する要素タイプと基になるコンテナタイプが同じである限り、別のスタックアダプタを初期化することもできます。例えば:

std::list<int> values{
    
     1, 2, 3 };
std::stack<int, std::list<int>> my_stack1(values);
std::stack<int, std::list<int>> my_stack = my_stack1;
//std::stack<int, std::list<int>> my_stack(my_stack1);

ご覧のとおり、基本コンテナを使用する場合とは異なり、スタックアダプタを使用して別のスタックを初期化する場合は、2つの方法があります。

スタックコンテナアダプタでサポートされるメンバー関数

ここに画像の説明を挿入
上記のメンバー関数の場合、次に例を示します。

#include <iostream>
#include <stack>
#include <list>

using namespace std;

int main()
{
    
    
    //构建 stack 容器适配器
    list<int> values{
    
     1, 2, 3 };
    stack<string, list<int>> my_stack(values);
    //查看 my_stack 存储元素的个数
    cout << "size of my_stack: " << my_stack.size() << endl;
    //将 my_stack 中存储的元素依次弹栈,直到其为空
    while (!my_stack.empty())
    {
    
      
        cout << my_stack.top() << endl;
        //将栈顶元素弹栈
        my_stack.pop();
    }
    return 0;
}

出力結果:

size of my_stack: 3
3
2
1

2と

スタックコンテナアダプタとは異なり、キューコンテナアダプタには2つの開口部があり、1つは入力データ専用で、もう1つは出力データ専用です。
ここに画像の説明を挿入
このストレージ構造の最大の特徴は、最初にキューに入る要素が最初にキューから出てくることもできることです。つまり、このコンテナアダプターを使用してデータを格納することには、「先入れ先出し(」)という特性があります。 FIFO ")"なので、キューもキューアダプタと呼ばれます。

1キューコンテナアダプタの作成

キューコンテナアダプタは、テンプレートクラスqueue <T、Container = deque>(Tはストレージ要素のタイプ、Containerは基になるコンテナのタイプを表す)の形式でヘッダーファイルにあり、で定義されています。 std名前空間。したがって、コンテナを作成する前に、プログラムに次の2行のコードを含める必要があります。

#include <queue>
using namespace std;

1

空のキューコンテナアダプタを作成し、使用する基になるベースコンテナのデフォルトのdequeコンテナを選択します。

std::queue<int> values;

このコード行を使用すると、格納可能なint型要素を正常に作成でき、最下層はdequeコンテナーのキューコンテナーアダプターを使用します。

2

キュー・コンテナー・アダプターが使用する基になるコンテナー・タイプを手動で指定することもできます。
たとえば、次の例では、リストコンテナをベースコンテナとして使用する空のキューコンテナアダプタを作成します。

std::queue<int, std::list<int>> values;

ベースコンテナのタイプを手動で指定する場合、格納されるデータのタイプは、キューコンテナアダプタによって格納される要素のタイプと一致している必要があることに注意してください。

3

コンテナー・タイプがキューの最下部で使用される基本コンテナー・タイプと同じである限り、基本コンテナーを使用して、キュー・コンテナー・アダプターを初期化できます。例えば:

std::deque<int> values{
    
    1,2,3};
std::queue<int> my_queue(values);

my_queueの最下層は、valuesタイプと一致するdequeコンテナーを使用し、すべてのintタイプ要素を格納するため、値を使用してmy_queueを初期化できます。

4

格納する要素タイプと基になるコンテナー・タイプが同じである限り、キュー・コンテナー・アダプターを介して別のキュー・コンテナー・アダプターを直接初期化することもできます。例えば:

std::deque<int> values{
    
    1,2,3};
std::queue<int> my_queue1(values);
std::queue<int> my_queue(my_queue1);
//或者使用
//std::queue<int> my_queue = my_queue1;

キュー・コンテナー・アダプターでサポートされるメンバー機能

ここに画像の説明を挿入
スタックと同様に、キューにはイテレータがないため、要素にアクセスする唯一の方法は、コンテナをトラバースし、訪問した要素を継続的に削除して次の要素にアクセスすることです。

最後の例:

#include <iostream>
#include <queue>
#include <list>

using namespace std;

int main()
{
    
    
    //构建 queue 容器适配器
    std::deque<int> values{
    
     1,2,3 };
    std::queue<int> my_queue(values);//{1,2,3}
    //查看 my_queue 存储元素的个数
    cout << "size of my_queue: " << my_queue.size() << endl;
    //访问 my_queue 中的元素
    while (!my_queue.empty())
    {
    
    
        cout << my_queue.front() << endl;
        //访问过的元素出队列
        my_queue.pop();
    }
    return 0;
}

出力結果;

size of my_queue: 3
1
2
3

3 priority_queue

priority_queueコンテナアダプタは、キューのストレージ構造もシミュレートします。つまり、このコンテナアダプタを使用して要素を格納するには、「一方の端から(キューの端と呼ばれます)、もう一方の端から(キュー)」であり、毎回のみアクセスできます。priority_queueのキューの先頭にある要素。
ただし、priority_queueコンテナアダプタでの要素の保存と取得は「先入れ先出し」の原則に従っていませんが、優先度が最も高い要素が最初にキューから出てきます。

では、priority_queueコンテナアダプタに格納されている要素の優先度はどのように評価されますか?非常に単純で、各priority_queueコンテナアダプタはソートルールを使用して作成されます。このルールに従って、コンテナアダプタに格納されている要素には優先度レベルがあります。

たとえば、現在priority_queueコンテナアダプタがあり、その並べ替えルールが最大から最小までの要素値に基づいているとします。このルールによれば、priority_queueで最大の値を持つ要素が最高の優先度を持つのは当然です。

priority_queueコンテナアダプタは、キューの先頭から削除されるたびに現在の最も優先度の高い要素であることを保証するために、新しい要素が入るたびに、確立された並べ替えルールに従って最も優先度の高い要素を見つけて、キューに移動しますチームのヘッド。同様に、priority_queueがチームのヘッドから要素を削除すると、現在の優先度が最も高い要素も検索され、チームのヘッドに移動されます。

priority_queueのこの機能に基づいて、コンテナアダプタは優先キューと呼ばれます。
priority_queueコンテナアダプタは次のように定義されています。

template <typename T,
        typename Container=std::vector<T>,
        typename Compare=std::less<T> >
class priority_queue{
    
    
    //......
}

ご覧のとおり、priority_queueコンテナアダプタテンプレートクラスは最大3つのパラメータを渡すことができ、それぞれの意味は次のとおりです。

  • typename T:ストレージ要素の特定のタイプを指定します。
  • typename Container:priority_queueの下部で使用される基本コンテナーを指定します。デフォルトではベクターコンテナーが使用されます。
  • typename Compare:コンテナ内の要素の優先度を評価するために従うソートルールを指定します。デフォルトでは、std :: lessを使用して要素を大きいものから小さいものにソートします。std:: greaterを使用してソートすることもできます。小さいものから大きいものまで、ただしそれ以上の要素この場合、カスタムの並べ替えルールが使用されます。

1priority_queueを作成します

priority_queueコンテナアダプタテンプレートはヘッダーファイルにあり、std名前空間で定義されているため、このタイプのコンテナを作成する前に、プログラムに次の2行のコードを含める必要があります。

#include <queue>
using namespace std;

1

空のpriority_queueコンテナアダプタを作成します。最下層はデフォルトのベクターコンテナを使用し、並べ替え方法もデフォルトのstd :: lessメソッドを使用します。

std::priority_queue<int> values;

2

priority_queueコンテナアダプタは、通常の配列または他のコンテナの指定された範囲のデータで初期化できます。

//使用普通数组
int values[]{
    
    4,1,3,2};
std::priority_queue<int> copy_values(values,values+4);//{4,3,2,1}
//使用序列式容器
std::array<int,4> values{
    
     4,1,3,2 };
std::priority_queue<int> copy_values(values.begin(),values.end());//{4,3,2,1}

上記の2つの方法では、配列またはコンテナに格納されている要素タイプが、priority_queueで指定されているストレージタイプと同じであることを確認する必要があることに注意してください。さらに、初期化に使用される配列またはコンテナ内のデータを並べ替える必要はありません。priority_queueはそれらを自動的に並べ替えます。

3

次のように、priority_queueで使用される基になるコンテナと並べ替えルールを手動で指定することもできます。

int values[]{
    
     4,1,2,3 };
std::priority_queue<int, std::deque<int>, std::greater<int>> copy_values(values, values+4);//{1,2,3,4}

priority_queueが提供するメンバー関数

ここに画像の説明を挿入
例えば:

#include <iostream>
#include <queue>
#include <array>
#include <functional>

using namespace std;

int main()
{
    
    
    //创建一个空的priority_queue容器适配器
    std::priority_queue<int>values;
    //使用 push() 成员函数向适配器中添加元素
    values.push(3);//{3}
    values.push(1);//{3,1}
    values.push(4);//{4,3,1}
    values.push(2);//{4,3,2,1}
    //遍历整个容器适配器
    while (!values.empty())
    {
    
    
        //输出第一个元素并移除。
        std::cout << values.top()<<" ";
        values.pop();//移除队头元素的同时,将剩余元素中优先级最大的移至队头
    }
    return 0;
}

出力結果:

4 3 2 1 %  

おすすめ

転載: blog.csdn.net/qq_24649627/article/details/108087991