C++ STLコンテナとアルゴリズムの実践的演習コード

回文判定プログラム

#include <iostream>
#include <string>
#include <algorithm>

bool is_palindrome(const std::string& str) {
    auto front = str.begin();
    auto back = str.rbegin();
    size_t mid = str.length() / 2;
    
    for(size_t i = 0; i < mid; ++i) {
        if(*front != *back)
            return false;
        ++front;
        ++back;
    }
    return true;
}

int main() {
    std::string input;
    std::cout << "文字列を入力してください: ";
    std::getline(std::cin, input);
    
    if(is_palindrome(input))
        std::cout << "回文です\n";
    else
        std::cout << "回文ではありません\n";
    
    return 0;
}

文字列フィルタリング付き回文チェック

#include <iostream>
#include <string>
#include <cctype>

std::string filter_string(std::string str) {
    auto it = str.begin();
    while(it != str.end()) {
        if(!std::isalpha(*it)) {
            it = str.erase(it);
        } else {
            *it = std::tolower(*it);
            ++it;
        }
    }
    return str;
}

bool check_palindrome(const std::string& filtered) {
    return std::equal(filtered.begin(), filtered.begin() + filtered.size()/2, 
                     filtered.rbegin());
}

int main() {
    std::string text;
    std::cout << "文字列を入力: ";
    std::getline(std::cin, text);
    
    std::string cleaned = filter_string(text);
    std::cout << (check_palindrome(cleaned) ? "回文" : "非回文") << std::endl;
    
    return 0;
}

単語当てゲームの実装

#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <string>

class WordGame {
private:
    std::vector<std::string> dictionary;
    
    void load_words(const std::string& filename) {
        std::ifstream file(filename);
        std::string word;
        while(file >> word)
            dictionary.push_back(word);
    }
    
public:
    WordGame(const std::string& filename) {
        std::srand(std::time(nullptr));
        load_words(filename);
    }
    
    void play() {
        std::string target = dictionary[std::rand() % dictionary.size()];
        std::string guess(target.size(), '-');
        std::string wrong_guesses;
        int attempts = 6;
        
        std::cout << "単語の長さ: " << target.size() 
                 << ", 間違い許容回数: " << attempts << std::endl;
        
        while(attempts > 0 && guess != target) {
            std::cout << "現在: " << guess << std::endl;
            char letter;
            std::cout << "文字を推測: ";
            std::cin >> letter;
            
            if(wrong_guesses.find(letter) != std::string::npos || 
               guess.find(letter) != std::string::npos) {
                std::cout << "既に試した文字です\n";
                continue;
            }
            
            size_t pos = target.find(letter);
            if(pos == std::string::npos) {
                std::cout << "不正解!\n";
                --attempts;
                wrong_guesses += letter;
            } else {
                std::cout << "正解!\n";
                do {
                    guess[pos] = letter;
                    pos = target.find(letter, pos + 1);
                } while(pos != std::string::npos);
            }
        }
        
        std::cout << (guess == target ? "正解!" : "ゲームオーバー") << std::endl;
    }
};

int main() {
    WordGame game("words.txt");
    game.play();
    return 0;
}

配列の重複除去テンプレート関数

#include <iostream>
#include <list>
#include <algorithm>

template<typename T>
size_t remove_duplicates(T arr[], size_t n) {
    std::list<T> temp(arr, arr + n);
    temp.sort();
    temp.unique();
    
    size_t new_size = 0;
    for(const auto& item : temp) {
        arr[new_size++] = item;
    }
    return new_size;
}

int main() {
    long data[] = {12, 2, 13, 12, 2, 55, 32, 44, 32, 100, 32, 12};
    size_t original = sizeof(data)/sizeof(data[0]);
    
    std::cout << "元データ: ";
    for(size_t i = 0; i < original; ++i)
        std::cout << data[i] << ' ';
    
    size_t new_size = remove_duplicates(data, original);
    
    std::cout << "\n重複除去後: ";
    for(size_t i = 0; i < new_size; ++i)
        std::cout << data[i] << ' ';
    
    std::cout << std::endl;
    return 0;
}

ATM待ち行列シミュレーション

#include <iostream>
#include <queue>
#include <ctime>

class Client {
private:
    long arrival_time;
    int process_duration;
    
public:
    Client() : arrival_time(0), process_duration(0) {}
    
    void initialize(long time) {
        process_duration = std::rand() % 3 + 1;
        arrival_time = time;
    }
    
    long get_arrival() const { return arrival_time; }
    int get_duration() const { return process_duration; }
};

bool new_client_arrived(double avg_interval) {
    return (std::rand() * avg_interval / RAND_MAX) < 1.0;
}

int main() {
    std::srand(std::time(nullptr));
    
    int max_queue, hours;
    double clients_per_hour;
    
    std::cout << "最大待ち人数: ";
    std::cin >> max_queue;
    std::cout << "シミュレーション時間(時間): ";
    std::cin >> hours;
    std::cout << "時間あたり客数: ";
    std::cin >> clients_per_hour;
    
    std::queue<Client> waiting_line;
    long total_cycles = 60 * hours;
    double interval = 60.0 / clients_per_hour;
    
    long rejected = 0, accepted = 0, served = 0;
    long total_wait = 0;
    int current_service = 0;
    
    for(long cycle = 0; cycle < total_cycles; ++cycle) {
        if(new_client_arrived(interval)) {
            if(waiting_line.size() >= max_queue) {
                ++rejected;
            } else {
                Client new_client;
                new_client.initialize(cycle);
                waiting_line.push(new_client);
                ++accepted;
            }
        }
        
        if(current_service <= 0 && !waiting_line.empty()) {
            Client next = waiting_line.front();
            waiting_line.pop();
            current_service = next.get_duration();
            total_wait += cycle - next.get_arrival();
            ++served;
        }
        
        if(current_service > 0) --current_service;
    }
    
    std::cout << "受付客数: " << accepted << "\nサービス済み: " << served
              << "\n断られた客: " << rejected << "\n平均待ち時間: " 
              << (double)total_wait / served << "分" << std::endl;
    
    return 0;
}

ランダム抽選システム

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>

std::vector<int> random_selection(int total, int picks) {
    std::vector<int> numbers(total);
    for(int i = 0; i < total; ++i)
        numbers[i] = i + 1;
    
    std::random_shuffle(numbers.begin(), numbers.end());
    std::vector<int> result(numbers.begin(), numbers.begin() + picks);
    std::sort(result.begin(), result.end());
    
    return result;
}

int main() {
    std::srand(std::time(nullptr));
    auto winners = random_selection(51, 6);
    
    std::cout << "当選番号: ";
    for(int num : winners)
        std::cout << num << ' ';
    std::cout << std::endl;
    
    return 0;
}

友人リストの集合操作

#include <iostream>
#include <set>
#include <iterator>
#include <algorithm>

std::set<std::string> input_names() {
    std::set<std::string> names;
    std::string name;
    
    while(std::cin >> name) {
        names.insert(name);
        if(std::cin.get() == '\n') break;
    }
    return names;
}

int main() {
    std::cout << "Matの友人を入力: ";
    auto mat_friends = input_names();
    
    std::cout << "Patの友人を入力: ";
    auto pat_friends = input_names();
    
    std::set<std::string> combined;
    std::set_union(mat_friends.begin(), mat_friends.end(),
                  pat_friends.begin(), pat_friends.end(),
                  std::inserter(combined, combined.begin()));
    
    std::cout << "共通友人: ";
    std::copy(combined.begin(), combined.end(),
             std::ostream_iterator<std::string>(std::cout, " "));
    
    return 0;
}

書籍レビュー管理システム

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>

struct BookReview {
    std::string title;
    int rating;
    double price;
};

bool input_review(BookReview& review) {
    std::cout << "書籍タイトル (終了はquit): ";
    std::getline(std::cin, review.title);
    if(review.title == "quit") return false;
    
    std::cout << "評価点: ";
    std::cin >> review.rating;
    std::cout << "価格: ";
    std::cin >> review.price;
    
    std::cin.ignore();
    return true;
}

void display_review(const std::shared_ptr<BookReview>& review) {
    std::cout << review->rating << "\t" << review->title 
              << "\t" << review->price << std::endl;
}

bool compare_title(const std::shared_ptr<BookReview>& a, 
                  const std::shared_ptr<BookReview>& b) {
    return a->title < b->title;
}

bool compare_rating_asc(const std::shared_ptr<BookReview>& a,
                       const std::shared_ptr<BookReview>& b) {
    return a->rating < b->rating;
}

bool compare_price_desc(const std::shared_ptr<BookReview>& a,
                       const std::shared_ptr<BookReview>& b) {
    return a->price > b->price;
}

int main() {
    std::vector<std::shared_ptr<BookReview>> reviews;
    BookReview temp;
    
    while(input_review(temp)) {
        reviews.push_back(std::make_shared<BookReview>(temp));
    }
    
    int choice;
    do {
        std::cout << "表示オプション: 0(元順), 1(タイトル順), 2(評価昇順), 3(価格降順), 4(終了): ";
        std::cin >> choice;
        
        switch(choice) {
            case 0: break;
            case 1: std::sort(reviews.begin(), reviews.end(), compare_title); break;
            case 2: std::sort(reviews.begin(), reviews.end(), compare_rating_asc); break;
            case 3: std::sort(reviews.begin(), reviews.end(), compare_price_desc); break;
        }
        
        if(choice != 4) {
            for(const auto& review : reviews)
                display_review(review);
        }
    } while(choice != 4);
    
    return 0;
}

タグ: C++ STL アルゴリズム コンテナ テンプレート

8月20日 14:20 投稿