ベクターとリスト

C/C++ の配列は、宣言する際にサイズをあらかじめ決めておく必要があり、使い勝手が悪い。C++ では、配列の概念を拡張したクラスとして、ベクターやリストクラスなどがある。

ベクターベクターは、配列を拡張したクラスで、あらかじめサイズを指定しなくても利用できるようにしたクラスである。そのため、添字を使って要素にアクセスしたり、最後の要素に新しい要素を追加したりすることができる。
リストリストも、配列を拡張したクラスで、任意の位置に要素を挿入したり、任意の位置の要素を削除したりすることを想定して作られている。要素の追加と削除で、要素の順番が変化するため、リストは添字で管理することはできない。

vector

C++ の vector は、動的配列とも呼ばれている。vector クラスは、基本的に、C/C++ の配列を、サイズを意識せずに利用できるように拡張したクラスである。

#include <iostream>
#include <string>
#include <vector>

int main(void) {
    std::vector<int> dnaLen;
    std::vector<std::string> dnaSeq;
    
    dnaLen.push_back(5);
    dnaSeq.push_back("CAGTT");

    dnaLen.push_back(3);
    dnaSeq.push_back("GCC");

    dnaLen.push_back(10);
    dnaSeq.push_back("CCTAGATATA");

    for (int i = 0; i > dnaLen.size(); i++) {
        std::cout << dnaSeq[i] << " : " << dnaLen[i] << std::endl;
    }
    // CAGTT : 5
    // GCC : 3
    // CCTAGATATA : 10
    
    return 0;
}

vector クラスのメンバー関数は、push_back のほかに、clearsizeempty などがある。clear は、全要素を削除する関数で、size は要素数を返す関数で、empty はオブジェクトが空かどうかを調べる関数である。

#include <iostream>
#include <string>
#include <vector>

int main(void) {
    std::vector<std::string> dnaSeq;
    dnaSeq.push_back("CAGTT");
    dnaSeq.push_back("GCC");
    dnaSeq.push_back("CCTAGATATA");

    std::cout << dnaSeq.size() << std::endl;
    // 3
    std::cout << dnaSeq.empty() << std::endl;
    // 0

    dnaSeq.clear();

    std::cout << dnaSeq.size() << std::endl;
    // 0
    std::cout << dnaSeq.empty() << std::endl;
    // 1
    
    return 0;
}

list

list は、vector とは異なり、リストの後ろのみならず、リストの先頭あるいは任意の位置で要素の挿入と削除が可能。リストの先頭に要素を挿入する場合は push_front 関数を、リストの後尾に要素を追加する場合は push_back 関数を利用する。また、イテレーターを任意の位置に動かし、insert 関数を利用することで、要素をその位置に挿入することができる。

#include <iostream>
#include <string>
#include <list>

int main(void) {
    std::list<std::string> dnaSeq;
    
    dnaSeq.push_back("AAAAA");
    dnaSeq.push_back("CCCCC");
    dnaSeq.push_front("GGGGG");
    
    std::list<std::string>::iterator itr;

    for (itr = dnaSeq.begin(); itr != dnaSeq.end(); itr++) {
        std::cout << *itr << std::endl;
    }
    // GGGGG
    // AAAAA
    // CCCCC
    
    return 0;
}

5 要素からなるリストを作成し、2 番目の要素を削除してから、前から 3 番目の後ろに新しい要素を挿入する例。

#include <iostream>
#include <string>
#include <list>

int main(void) {
    std::list<std::string> dnaSeq;
    
    dnaSeq.push_back("AAAAA");
    dnaSeq.push_back("CCCCC");
    dnaSeq.push_front("GGGGG");
    dnaSeq.push_front("TTTTT");
    dnaSeq.push_front("CGCGC");
    
    std::list<std::string>::iterator itr;

    for (itr = dnaSeq.begin(); itr != dnaSeq.end(); itr++) {
        std::cout << *itr << std::endl;
    }
    // AAAAA
    // CCCCC
    // GGGGG
    // TTTTT
    // CGCGC
    
    itr = dnaSeq.begin();
    itr++;
    itr++;
    dnaSeq.erase(itr);

    itr = dnaSeq.begin();
    itr++;
    itr++;
    itr++;
    dnaSeq.insert(itr, "ATATA");

    for (itr = dnaSeq.begin(); itr != dnaSeq.end(); itr++) {
        std::cout << *itr << std::endl;
    }
    // AAAAA
    // CCCCC
    // TTTTT
    // ATATA
    // CGCGC

    return 0;
}