std::multimap 获取两个范围

发布于 2024-12-03 07:12:14 字数 702 浏览 1 评论 0原文

我正在使用 C++ std::multimap 并且必须循环遍历两个不同的键。除了创建两个范围并分别循环这些范围之外,还有其他有效的方法吗?

这就是我现在这样做的方式:

std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range;
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2;

// get the range of String key
range = multimap.equal_range(key1);
range2 = multimap.equal_range(key2);

for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it)
{
    ...
}
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

I'm using a C++ std::multimap and I have to loop over two different keys. Is there an efficient way to do this other than creating two ranges and looping over those ranges seperately?

This is the way im doing it now:

std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range;
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2;

// get the range of String key
range = multimap.equal_range(key1);
range2 = multimap.equal_range(key2);

for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it)
{
    ...
}
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

城歌 2024-12-10 07:12:14

您开始使用的代码是最简单的。

如果您确实想在同一循环中迭代两个范围,则可以创建一个自定义迭代器,它接受两个迭代器范围,迭代第一个范围,直到完成,然后切换到第二个范围。这可能比它的价值更麻烦,因为您需要自己实现所有迭代器成员。

编辑:我想太多了;只需将两个循环修改为一个循环就很容易了。

for (std::multimap<String, Object*>::iterator it = range.first; it != range2.second; ++it)
{
    if (it == range.second)
    {
        it = range2.first;
        if (it == range2.second)
            break;
    }
    ...
}

The code you started with is the most straightforward.

If you'd really like to iterate over two ranges in the same loop, you can create a custom iterator that takes two iterator ranges, iterates over the first until it's done then switches to the second. This is probably more trouble than it's worth, as you'd need to implement all of the iterator members yourself.

Edit: I was overthinking this; it's easy just to modify the two loops into a single one.

for (std::multimap<String, Object*>::iterator it = range.first; it != range2.second; ++it)
{
    if (it == range.second)
    {
        it = range2.first;
        if (it == range2.second)
            break;
    }
    ...
}
尝蛊 2024-12-10 07:12:14

当然,Boost 就是这么做的。使用 Boost.Range 及其 join 函数将获得您想要的结果。有关更多详细信息,请参阅 Boost Range 库:顺序遍历两个范围

Boost does this, of course. Using Boost.Range and its join function will get you what you want. See Boost Range Library: Traversing Two Ranges Sequentially for more details.

北渚 2024-12-10 07:12:14

如果您有权访问 C++-11(Visual Studio 10+、gcc-4.5+)并被允许使用它 auto 是一个真正的宝石:

// get the range of String key
auto range = multimap.equal_range(key1);
auto range2 = multimap.equal_range(key2);

for (auto it = range.first; it != range.second; ++it)
{
    ...
}
for (auto it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

无论如何,我只会测试按键并且只执行如果 key2 != key1,则第二次循环。每次在循环中检查迭代器都会产生一些成本。

第一个范围与第二个范围的 std::set_difference 可能会简化代码。
也许 std::set_union 两个范围并通过 back_inserter 插入到一个集合中,这样你就只得到一个副本?

一些实验可能是有序的。不要忘记将您的第一个猜测加入其中。速度方面的表现可能会让您感到惊讶。除非范围通常很长和/或循环操作成本很高,否则可能不值得为额外的簿记而头痛。

If you have access to C++-11 (Visual Studio 10+, gcc-4.5+) and are allowed to use it auto is a real gem:

// get the range of String key
auto range = multimap.equal_range(key1);
auto range2 = multimap.equal_range(key2);

for (auto it = range.first; it != range.second; ++it)
{
    ...
}
for (auto it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

Anyway, I would just test the keys and only do the second loop if key2 != key1. Checking iterators each time in a loop has some cost.

A std::set_difference of the first range from the second might streamline the code.
Maybe std::set_union the two ranges and insert through back_inserter into a set so you only get one copy?

Some experiments may be in order. Don't forget to put your first guess in the mix. It might surprise you by being just fine in terms of speed. Unless the ranges are typically very long and/or the loop operation is expensive it may not be worth the headache of extra bookkeeping.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文