You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++98中向量过滤代码的优化方案咨询

优化C++98下的姓名匹配代码

嘿,我来帮你梳理下这个C++98环境下的代码优化思路!首先得说,你之前尝试抽象类的路子可能确实有点过度设计了——这个场景的核心需求其实是高效查找和减少重复代码,不用搞复杂的类层次。咱们一步步来优化:

核心瓶颈:线性查找的效率问题

原代码里用std::vector存储男女姓名,然后嵌套线性查找,时间复杂度是O(MR + WR)(M是男性姓名数,W是女性,R是租客数)。如果数据量稍微大一点,这个效率会很低。C98里咱们可以用std::set(std::unordered_set是C11才有的),它的查找是O(logN),能大幅提升速度。

具体优化方案

1. 用std::set存储男女姓名,提升查找效率

把menNames和womenNames换成std::set<std::string>,这样查找的时候直接用set::find(),比遍历vector快得多。

2. 提取通用函数,减少重复代码

文件读取的逻辑重复了三次,咱们可以写一个通用的函数来读取文件到容器里;另外查找男女姓名的逻辑也可以合并,避免两次循环。

3. 边读租客姓名边处理,节省内存

原代码先把所有租客姓名读到renterNames里再处理,其实可以直接读一个处理一个,不用额外存整个租客列表,节省内存空间。

4. 简化迭代器使用

C++98支持在for循环的初始化部分定义迭代器变量,不用提前声明一堆迭代器,代码更整洁。

优化后的代码示例

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

// 通用函数:读取文件内容到容器(支持vector或set)
template <typename Container>
bool readNamesFromFile(const std::string& filePath, Container& container) {
    std::ifstream file(filePath.c_str());
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << filePath << std::endl;
        return false;
    }
    std::string name;
    while (file >> name) {
        container.insert(container.end(), name); // vector用push_back,set用insert都兼容
    }
    file.close();
    return true;
}

int main() {
    std::set<std::string> menNames;
    std::set<std::string> womenNames;
    std::vector<std::string> knownRenters;
    std::vector<std::string> unknownRenters;

    // 读取姓名文件
    readNamesFromFile("resources/men_names.txt", menNames);
    readNamesFromFile("resources/women_names.txt", womenNames);

    // 处理租客姓名:边读边判断
    std::ifstream renters("resources/renter_names.txt");
    if (!renters.is_open()) {
        std::cerr << "Failed to open renter names file!" << std::endl;
        return 1;
    }

    std::string renterName;
    while (renters >> renterName) {
        bool isKnown = false;
        // 查找男性姓名
        if (menNames.find(renterName) != menNames.end()) {
            knownRenters.push_back(renterName);
            isKnown = true;
        }
        // 没找到再查女性
        else if (womenNames.find(renterName) != womenNames.end()) {
            knownRenters.push_back(renterName);
            isKnown = true;
        }
        // 都没找到就归为未知
        if (!isKnown) {
            unknownRenters.push_back(renterName);
        }
    }
    renters.close();

    std::cout << knownRenters.size() << '\n';
    std::cout << unknownRenters.size() << '\n';
    std::cin.get();
    return 0;
}

额外的小优化

如果男女姓名不需要分开存储,还可以把它们合并到一个std::set里,这样只需要一次查找就能判断是否是已知姓名,代码会更简洁:

std::set<std::string> allKnownNames;
readNamesFromFile("resources/men_names.txt", allKnownNames);
readNamesFromFile("resources/women_names.txt", allKnownNames);

// 处理租客时直接查这个集合
while (renters >> renterName) {
    if (allKnownNames.count(renterName)) {
        knownRenters.push_back(renterName);
    } else {
        unknownRenters.push_back(renterName);
    }
}

关于你之前的抽象类尝试

确实没必要用抽象类来实现实体对象——这个场景里没有复杂的多态需求,只是简单的存储和查找,用标准容器加通用函数就足够解决问题,过度设计反而会增加代码冗余和维护成本。

内容的提问来源于stack exchange,提问作者Ilya Zhidkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:01:09