测试_第16章_实战项目.cpp

← 测试总览 · 目录

编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第16章_实战项目.cpp -o t && ./t(需先 cd 测试/

// 第16章测试:实战项目核心函数
#include <print>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <cstdint>

int failures = 0;
#define CHECK(expr)                                                         \
    do {                                                                    \
        if (!(expr)) {                                                      \
            ++failures;                                                     \
            std::println("FAIL 第{}行: {}", __LINE__, #expr);              \
        }                                                                   \
    } while (0)

// 项目一:词频统计核心(从文本流统计词频,便于测试)
std::map<std::string, int> count_words(std::istream& in) {
    std::map<std::string, int> freq;
    std::string word;
    while (in >> word) {
        std::string clean;
        for (char c : word) {
            if (std::isalpha(static_cast<unsigned char>(c)))
                clean.push_back(std::tolower(static_cast<unsigned char>(c)));
        }
        if (!clean.empty()) ++freq[clean];
    }
    return freq;
}

// 项目二:TODO 结构
struct Task {
    std::string title;
    int priority = 0;
    bool done = false;
};
using TaskList = std::vector<Task>;

// 序列化:tasks.txt 读写(用字符串流测)
std::string serialize(const TaskList& tasks) {
    std::ostringstream out;
    for (const auto& t : tasks)
        out << t.done << ' ' << t.priority << ' ' << t.title << '\n';
    return out.str();
}

TaskList deserialize(std::istream& in) {
    TaskList tasks;
    Task t;
    while (in >> t.done >> t.priority) {
        std::getline(in, t.title);
        if (!t.title.empty() && t.title.front() == ' ')
            t.title.erase(0, 1);
        tasks.push_back(t);
    }
    return tasks;
}

// 项目三:素数工具
std::vector<std::int64_t> sieve_prime_factors(std::int64_t n) {
    std::vector<std::int64_t> factors;
    for (std::int64_t p = 2; p * p <= n; ++p) {
        while (n % p == 0) { factors.push_back(p); n /= p; }
    }
    if (n > 1) factors.push_back(n);
    return factors;
}

std::vector<int> primes_below(int limit) {
    std::vector<bool> composite(limit + 1, false);
    std::vector<int> primes;
    for (int i = 2; i <= limit; ++i) {
        if (!composite[i]) {
            primes.push_back(i);
            for (std::int64_t j = (std::int64_t)i * i; j <= limit; j += i)
                composite[j] = true;
        }
    }
    return primes;
}

template <typename T>
bool is_prime(T n) {
    if (n < 2) return false;
    for (T i = 2; i * i <= n; ++i)
        if (n % i == 0) return false;
    return true;
}

int main() {
    // 词频统计
    std::istringstream text("Hello hello, World! world hello");
    auto freq = count_words(text);
    CHECK(freq["hello"] == 3);
    CHECK(freq["world"] == 2);
    CHECK(freq.size() == 2);

    // TODO 序列化往返
    TaskList tasks{{"买牛奶", 3, false}, {"写作业", 1, true}};
    std::string serial = serialize(tasks);
    std::istringstream in(serial);
    auto back = deserialize(in);
    CHECK(back.size() == 2);
    CHECK(back[0].title == "买牛奶" && back[0].priority == 3);
    CHECK(back[1].title == "写作业" && back[1].done == true);

    // 质因数分解
    CHECK((sieve_prime_factors(100) == std::vector<std::int64_t>{2, 2, 5, 5}));
    CHECK((sieve_prime_factors(97) == std::vector<std::int64_t>{97}));
    CHECK((sieve_prime_factors(1) == std::vector<std::int64_t>{}));

    // 埃氏筛
    auto primes = primes_below(100);
    CHECK(primes.size() == 25);                         // 100 内有 25 个质数
    CHECK(primes.front() == 2);
    CHECK(primes.back() == 97);

    // is_prime
    CHECK(is_prime(2));
    CHECK(is_prime(97));
    CHECK(!is_prime(1));
    CHECK(!is_prime(4));
    CHECK(!is_prime(121));

    if (failures == 0) std::println("全部通过");
    return failures;
}