为了账号安全,请及时绑定邮箱和手机立即绑定

同时迭代两个或多个容器的最佳方法是什么

同时迭代两个或多个容器的最佳方法是什么

C++
跃然一笑 2019-10-15 15:23:43
C ++ 11提供了多种遍历容器的方式。例如:基于范围的循环for(auto c : container) fun(c)std :: for_eachfor_each(container.begin(),container.end(),fun)但是,建议对两个(或更多个)相同大小的容器进行迭代以完成类似任务的方法是:for(unsigned i = 0; i < containerA.size(); ++i) {  containerA[i] = containerB[i];}
查看完整描述

3 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

但是:我会遍历索引。但是不使用经典for循环,而是使用基于范围for的索引循环:


for(unsigned i : indices(containerA)) {

    containerA[i] = containerB[i];

}

indices是一个简单的包装函数,它返回索引的(延迟计算)范围。由于实现虽然简单,但将其发布到此处有点太长,因此可以在GitHub上找到实现。


此代码与使用手动经典循环一样有效for。


如果这种模式经常出现在您的数据中,请考虑使用具有zip两个序列并产生一系列元组(对应于成对的元素)的另一种模式:


for (auto& [a, b] : zip(containerA, containerB)) {

    a = b;

}

的实现zip留给读者练习,但是从实现开始很容易indices。


(在C ++ 17之前,您必须编写以下代码:)


for (auto items&& : zip(containerA, containerB))

    get<0>(items) = get<1>(items);


查看完整回答
反对 回复 2019-10-15
?
慕少森

TA贡献2019条经验 获得超9个赞

对于您的特定示例,只需使用


std::copy_n(contB.begin(), contA.size(), contA.begin())

对于更一般的情况,您可以使用Boost.Iterator的zip_iterator,它具有一个小的函数,使其可以在基于范围的for循环中使用。在大多数情况下,这将起作用:


template<class... Conts>

auto zip_range(Conts&... conts)

  -> decltype(boost::make_iterator_range(

  boost::make_zip_iterator(boost::make_tuple(conts.begin()...)),

  boost::make_zip_iterator(boost::make_tuple(conts.end()...))))

{

  return {boost::make_zip_iterator(boost::make_tuple(conts.begin()...)),

          boost::make_zip_iterator(boost::make_tuple(conts.end()...))};

}


// ...

for(auto&& t : zip_range(contA, contB))

  std::cout << t.get<0>() << " : " << t.get<1>() << "\n";

现场示例。


然而,对于全面的通用性,你可能想要的东西更像是这样,这将正常工作,数组和用户定义的类型没有成员begin()/ end()但这样做有begin/ end功能在他们的命名空间。同样,这将允许用户const通过zip_c...功能专门访问。


而且,如果您像我一样倡导漂亮的错误消息,那么您可能需要this,它检查是否将任何临时容器传递给任何zip_...函数,如果是,则打印一条漂亮的错误消息。


查看完整回答
反对 回复 2019-10-15
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

我不知道为什么没人提到这个:


auto ItA = VectorA.begin();

auto ItB = VectorB.begin();


while(ItA != VectorA.end() || ItB != VectorB.end())

{

    if(ItA != VectorA.end())

    {

        ++ItA;

    }

    if(ItB != VectorB.end())

    {

        ++ItB;

    }

}

PS:如果容器大小不匹配,则必须将代码放入if语句内。


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 1357 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信