我有正在读入矢量的数据文件。示例:
West Ham 38 12
Leicester City 38 13
在实际文件中,名称后面还有更多的双打。无论如何,以前我用过这种搜索:
vector<Team>newTeams; //vector of Team objects
string homeName;
cout << "Enter home team name: ";
cin >> homeName;
cout << endl;
Team ht;
for(Team team : newTeams)
{
if(team.getName() == homeTeam)
{
ht = team;
}
}
基本上我会浏览一个向量并查找特定的团队名称。如果我找到了团队名称,我就派团队去了。然后,我会用ht来获取所需的数据,即:
ht.getHomeGamesPlayed();
ht.getPoints();
ht.getHomeGoalsScored();
所以,我的问题是:有更好的搜索方式吗?(使用名称地图+双打矢量?):
map<name, vector<doubles>>;
另外,如何使搜索不区分大小写?即我输入莱斯特而不是莱斯特城,莱斯特城仍然会被选中?
UPD: 好像我想出来了,如果你有兴趣,这是代码:
string homeName;
cout << "Name: " << endl;
cin >> homeName;
Team ht;
for (Team team : dataTable) {
if (strstr(team.getName().c_str(), homeName.c_str()))
{
ht = team;
}
}
因此,当我输入Leic时,它选择莱斯特城(当我输入leic时,它不起作用)
答案 0 :(得分:3)
是的,std::map
更适合您的问题。那样std::unordered_map
。
要获得不区分大小写的匹配项,可以使用已转换为全部大写或全部小写的字符串作为映射键。然后单独存储原始名称。
std::map<std::string, std::pair<std::string, std::vector<double>>> mymap;
如果您需要部分匹配,例如当您键入Leicester City
时找到leicester
,您现在使用的向量方法可能是最好的。如果您只需要匹配名称的第一个部分,您仍然可以使用std::map
并使用map::lower_bound
查找搜索的起始位置。
答案 1 :(得分:1)
这个问题有一些解决方案。我建议的是具有多个输入位置的基数树。
首先,创建一个地图或集合或任何东西来保存你的对象。然后,创建一个基数树,索引某个给定宽度的每个部分匹配,例如
abcde fge
为“abcde fge”,“bcde fge”,“cde fge”,...“e”创建一个条目。指向您的(多)地图值。您可以使用基数树的属性,您可以轻松找到具有给定前缀的所有值,以执行快速搜索,以查找大约O(1)中的给定子字符串的所有匹配(或N大小搜索项中的O(N) )如果你有一个固定的输入大小。但请注意,树的构造按可搜索材料大小的O(n ^ 2)缩放,为了解决这个问题,您可以限制索引的搜索项(例如50个字符)的大小,或者索引增量后跟多次搜索(例如索引“abcdefg”“cdefg”和“efg”,然后当搜索“def”时搜索“def”和“ef”,“ef”导致前缀与efg匹配。)< / p>
请注意,搜索字符串必须至少与您跳过的宽度一样长,否则您必须搜索整个树..