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
相关产品推荐
相关产品推荐

