C++における文字列とコンテナの実用的な操作技法

文字列処理の基本操作

初期化方法:

std::string text1;                    // 空文字列
std::string text2 = "greetings";      // リテラル初期化
std::string text3(text2);             // コピー初期化
std::string text4("planet");          // C文字列からの初期化
std::string text5(6, 'x');            // 6個の'x'で構成

長さ取得・アクセス:

size_t length = text1.length();       // .size()も同等
char firstChar = text1[0];            // 書き換え可能
text1[0] = 'H';                       // 直接代入可

結合・比較:

text1 += text2;                       // 結合演算子
text1.append("suffix");               // 追加メソッド

if (text1 == text2) { /* 同一 */ }    // 等値比較
int cmp = text1.compare(text2);       // 辞書順比較 (-1,0,1)

検索・部分文字列:

size_t found = text1.find("key");     // 前方検索
if (found != std::string::npos) { ... }

size_t last = text1.rfind('z');       // 後方検索
std::string part = text1.substr(2, 4); // 位置2から4文字切り出し

編集操作:

text1.insert(3, "INSERTED");          // 挿入
text1.erase(1, 5);                    // 削除(位置1から5文字)
text1.replace(0, 3, "NEW");           // 置換(位置0から3文字を"NEW"に)
text1.clear();                        // 全削除

カスタムソートを伴うsetの活用

struct MenuItem {
    std::string name;
    int priority;

    bool operator<(const MenuItem& other) const {
        if (priority != other.priority)
            return priority > other.priority; // 高優先度が先
        return name < other.name;             // 同優先度なら名前昇順
    }
};

std::set<MenuItem> menu;
menu.insert({"Sushi", 9});
menu.insert({"Ramen", 8});

// イテレート
for (const auto& item : menu) {
    std::cout << item.name << ": " << item.priority << "\n";
}

重複許容と高速検索のコンテナ

重複要素を保持するmultisetや、ハッシュベースのunordered_setは以下のように利用:

std::vector<int> intersect(const std::vector<int>& a, const std::vector<int>& b) {
    std::unordered_set<int> lookup(a.begin(), a.end());
    std::unordered_set<int> result;

    for (int x : b) {
        if (lookup.count(x)) {
            result.insert(x);
        }
    }
    return std::vector<int>(result.begin(), result.end());
}

キー-値マッピング:unordered_map

std::unordered_map<std::string, int> scoreMap;
scoreMap["Alice"] = 95;
scoreMap["Bob"] = 87;

// 削除・更新
scoreMap.erase("Bob");
scoreMap["Alice"] = 98;

// 安全な参照
if (scoreMap.contains("Alice")) {
    int s = scoreMap.at("Alice");
}

// 範囲forで走査
for (const auto& [name, score] : scoreMap) {
    std::cout << name << " → " << score << "\n";
}

// Two Sum問題の応用例
std::vector<int> findPair(const std::vector<int>& nums, int target) {
    std::unordered_map<int, int> indexMap;
    for (int i = 0; i < nums.size(); ++i) {
        int complement = target - nums[i];
        if (indexMap.count(complement)) {
            return {indexMap[complement], i};
        }
        indexMap[nums[i]] = i;
    }
    return {};
}

優先度キューによる効率的データ管理

#include <queue>

// デフォルト: 最大ヒープ
std::priority_queue<int> maxHeap;
maxHeap.push(10);
maxHeap.push(30);
maxHeap.push(20);

std::cout << maxHeap.top(); // 出力: 30
maxHeap.pop();

// 最小ヒープ版
std::priority_queue<int, std::vector<int>, std::greater<>> minHeap;
minHeap.push(10);
minHeap.push(30);
minHeap.push(20);

std::cout << minHeap.top(); // 出力: 10

タグ: cpp String set unordered_map priority_queue

6月13日 18:39 投稿