早上好, 我有一个以这种方式定义的多重地图
multimap<string, string> H_test;
带有用户的价值(同一作者以随机顺序写的多本书)
H_test.insert(pair<string, string>(author, book));
我希望得到类似的输出:
Author I // one author
Book A // all book written by this author
Book B
Author II
Book K
Author III
Book C
Book D
Book E
使用此代码
for (multimap<string,string>::iterator it = H_test.begin(); it != H_test.end(); it++)
{
//if ()
{
pair <multimap<string, string>::iterator, multimap<string, string>::iterator> ret;
ret = H_test.equal_range(it->first);
std::cout << it->first << endl;
for (multimap<string, string>::iterator sd = ret.first; sd != ret.second; sd++)
{
cout << "\t" << sd->second << endl;
}
}
}
我获得此输出
Author I
Book A
Book B
Author I
Book A
Book B
Author II
Book K
Author III
..
在我看来,它会打印第一个键的名称(以及所有具有相同作者的书籍),然后它会转到第二个nome(具有相同名称),然后重写所有内容。 你知道怎么解决吗?
由于
答案 0 :(得分:1)
upper_bound
是你的朋友。您想要使用类似这样的内容:
auto start = begin(H_test);
while (start != end(H_test)) {
auto finish = H_test.upper_bound(start->first);
cout << "Author: " << start->first << endl;
for_each(start, finish, [](const auto& i) { cout << "Book: " << i.second << endl; });
start = finish;
}
注意:您可以使用cbegin
和cend
,而不是H_test
const
。
修改强>
它帮助我将multimap
概念化为pair
的排序数组,其中pair
中的第一个元素是键,第二个元素是值。这实际上是我们所做的:
pair
作为我们的迭代器迭代所有start
,从第一个pair
开始:auto start = begin(H_test)
并转到最后pair
multimap
:while(start != end(H_test))
pair
的范围,因为我们将使用upper_bound
函数找到一个指向一个结尾的迭代器我链接了上面的详细信息:auto finish = H_test.upper_bound(start->first)
cout << "Author: " << start->first << endl
for_each
打印start
到finish
定义的范围内的每本书,并使用lambda打印该对的值,然后移到下一个line:for_each(start, finish, [](const auto& i) { cout << "Book: " << i.second << endl; });
start
设置为下一个范围的开头,下次将在循环中打印:start = finish
答案 1 :(得分:0)
只需遍历多图,并且由于所有具有相同作者的元素被组合在一起,您只需要检测作者的更改,以便知道您已转移到下一位作者,此时您将打印作者的姓名。将lastAuthor
预设为与真实作者无法匹配的内容。这在O(n)
string lastAuthor = "**SENTINEL**";
for (const auto& elem : H_test)
{
if(lastAuthor != elem.first)
{
cout << "Author: " << elem.first << '\n';
lastAuthor = elem.first;
}
cout << "Book: " << elem.second << '\n';
}