2016-09-06 60 views
1

我有正在读入矢量的数据文件。例如:对象矢量搜索未来对象的使用?

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来获得所需的数据,即:

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,这不是” t工作虽然)

+1

无关,但我希望你打算在这个代码的多个地方在哪里复制分配正在发生。显然你的班级还没有涵盖*引用*。 – WhozCraig

+0

当你复制小对象时,复制任务通常是正常的......但是,团队常量&可能会更好...... – Exaeta

+0

@WhozCraig如果你能告诉我如何在我的例子中使用引用,我会超过乐于学习(我现在没有参加任何课程,这只是为了好玩) – illia

回答

3

是的,std::map将是一个更适合您的问题。 std::unordered_map也是如此。

要获取不区分大小写的匹配项,可以使用已转换为全部大写或全部小写字符串的字符串作为映射键。然后分开存储原始名称。

std::map<std::string, std::pair<std::string, std::vector<double>>> mymap; 

如果您需要部分匹配,例如当您键入leicester时,发现Leicester City,您现在使用的矢量方法可能是最好的。如果只需要匹配的第一个部分名称,则仍然可以使用std::map并使用map::lower_bound找到搜索的起始位置。

1

这个问题有几个解决方案。我建议的是一个有多个输入位置的基数树。

首先,创建一个映射或设置或任何持有您的对象。然后,你创建一个基数树,索引一些给定宽度的每个部分匹配,例如

ABCDE FGE

创建 “ABCDE FGE”, “BCDE FGE”, “CDE FGE” ...... “E” 的条目。指向你的(多)地图值。您可以使用基数树的属性,您可以使用给定的前缀轻松找到所有值,以执行快速搜索,以便在O(1)(或O(N))大小的搜索词中找到给定子字符串的所有匹配)提供了一个固定的输入大小。但请注意,树的构建以可搜索材料的大小为O(n^2)进行缩放,为了弥补这一点,您可以限制索引的搜索项的大小(例如50个字符)或索引(例如,索引“abcdefg”,“cdefg”和“efg”),然后当搜索“def”时搜索“def”和“ef”,“ef”将导致与efg的前缀匹配。)

注意,搜索字符串必须至少只要你跳过宽度,否则你就必须搜索整个目录树..