[英]Optimizing filtering of a vector in C++ 98
I was given a following task: create a text file which contains men, women and unknown names. 我得到了以下任务:创建一个包含男人,女人和未知名称的文本文件。 Try to implement a filter that will compare those names with real names (so 3 files on input in total: men, women and let's say renters). 尝试实现一个过滤器,将那些名称与真实名称进行比较(因此,总共输入了3个文件:男性,女性,比如说房客)。 While filtering put matching names in their appropriate containers. 过滤时,将匹配的名称放入其适当的容器中。 It seemed to me pretty straight forward so I did it the way I provide underneath. 在我看来,这很简单,所以我按照下面提供的方式进行了操作。
My question is: Is there a way how to optimize this code? 我的问题是: 有没有一种方法可以优化此代码?
I tried to use abstract classes and create 4 different objects (Man, Woman, Known, Unknown) based on abstract entity. 我试图使用抽象类,并基于抽象实体创建4个不同的对象(男人,女人,已知,未知)。 But the amount of code was still large for such a simple task. 但是对于这样一个简单的任务,代码量仍然很大。 Another idea was to use lambda expressions, but I am limited to C++ 98 only. 另一个想法是使用lambda表达式,但是我仅限于C ++ 98。
I think I am overthinking it... 我想我想得太多了...
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::ifstream men("resources/men_names.txt");
std::ifstream women("resources/women_names.txt");
std::ifstream renters("resources/renter_names.txt");
std::vector<std::string> menNames;
std::vector<std::string> womenNames;
std::vector<std::string> renterNames;
std::vector<std::string> knownRenters;
std::vector<std::string> unknownRenters;
std::string name;
while (men >> name)
menNames.push_back(name);
men.close();
while (women >> name)
womenNames.push_back(name);
women.close();
while (renters >> name)
renterNames.push_back(name);
renters.close();
std::vector<std::string>::iterator itMen;
std::vector<std::string>::iterator itWomen;
std::vector<std::string>::iterator itRenters;
for (itRenters = renterNames.begin(); itRenters != renterNames.end(); itRenters++)
{
bool found = false;
for (itMen = menNames.begin(); itMen != menNames.end(); itMen++)
{
if ((*itMen) == (*itRenters))
{
found = true;
knownRenters.push_back((*itMen));
}
}
if (!found)
{
for (itWomen = womenNames.begin(); itWomen != womenNames.end(); itWomen++)
{
if ((*itWomen) == (*itRenters))
{
found = true;
knownRenters.push_back((*itWomen));
}
}
}
if (!found)
unknownRenters.push_back((*itRenters));
}
std::cout << knownRenters.size() << '\n';
std::cout << unknownRenters.size() << '\n';
std::cin.get();
return 0;
}
A shortening of your existing code. 缩短现有代码。 This should be all C++98 这应该都是C ++ 98
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <iterator>
int main()
{
std::ifstream men("resources/men_names.txt");
std::ifstream women("resources/women_names.txt");
std::set<std::string> peopleNames;
peopleNames.insert(std::istream_iterator<std::string>(men), std::istream_iterator<std::string>());
peopleNames.insert(std::istream_iterator<std::string>(women), std::istream_iterator<std::string>());
std::ifstream renters("resources/renter_names.txt");
std::vector<std::string> knownRenters;
std::vector<std::string> unknownRenters;
for (std::string name; renters >> name; )
{
if (peopleNames.count(name))
knownRenters.push_back(name);
else
unknownRenters.push_back(name);
}
std::cout << knownRenters.size() << '\n';
std::cout << unknownRenters.size() << '\n';
std::cin.get();
return 0;
}
You don't care whether a renter is male or female, just if they have a recognised name. 您不在乎租户是男性还是女性,即使他们有公认的名字。 So, don't store two flat vectors of known names, store a single std::set<std::string>
of all recognised names (or a sorted vector, or a std::unordered_set
if you're ever allowed to use C++11). 因此,请勿存储两个已知名称的平面向量,而应存储所有已识别名称的单个std::set<std::string>
(或排序后的向量,或者如果允许使用std::unordered_set
话) C ++ 11)。
Then, instead of doing (at most) two linear searches per renter, you can do a single logarithmic-time lookup (or constant-time for the C++11 version). 然后,您可以(仅对数时间)查找(对于C ++ 11版本为常数时间),而不是(每个租户最多)进行两次线性搜索。
You also don't seem to care about the names of the renters who were recognised (or not), so don't keep two result vectors: just increment a known
or unknown
counter. 您似乎也不必关心被认可(或未被认可)的房客的姓名,因此不要保留两个结果向量:仅增加known
或unknown
计数器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.