【问题标题】:Iterator on nth element of each vector in vector<vector<T>>vector<vector<T>> 中每个向量的第 n 个元素的迭代器
【发布时间】:2019-08-07 02:06:41
【问题描述】:

假设我有一些T 类型的向量,即vector&lt;vector&lt;T&gt;&gt; vec

现在,我想对每个嵌套向量的第 n 个元素执行一些 STL 算法。例如,我只想对每个向量的第 n 个元素进行排序,而保留所有其他元素不变。

为此,我需要某种迭代器,以便它遍历嵌套向量,但取消引用迭代器将产生向量的第 n 个元素。这是一种合理的方法吗?如果是,是否有任何现有的实现?最好在 STL 中。

动机:我需要对嵌套向量执行一些 STL 算法,但不能使用任何额外空间。

示例:Adaptor&lt;N&gt;(It iterator) 成为我们想要的迭代器类,它是嵌套数组中位置 N 处元素的迭代器,在返回的迭代器上调用 next 会将我们带到在下一个嵌套数组中位置N 的元素。

vector<vector<int>> vec {{1,3,2}, {4,1,10}, {3,3,3}, {9,8,7}}
sort(Adaptor<2>(vec.begin()), Adaptor<2>(vec.end()));

将产生vec

{{1,3,2}, {4,1,3}, {3,3,7}, {9,8,10}}

【问题讨论】:

  • 1) 不,这不是一个合理的方法,2) 没有实际意义,没有现有的实现。这似乎回答了你的问题。
  • 您能否解释一下为什么不合理?
  • 因为 C++ 迭代器根本无法以这种方式工作。取消引用迭代器会产生迭代器引用的值,而不是其他完全不相关的值。
  • 当然可以,但是您不能创建自己的迭代器类来提供取消引用的覆盖吗?该值并非完全不相关。事实上,它总是在基本迭代器前面的 n 个位置。
  • @SamVarshavchik 有什么不合理的?有很多迭代器适配器(尽管few in 标准库)

标签: c++ algorithm iterator


【解决方案1】:

如果您能够使用 Boost,boost::iterator_adaptor 可以让这相当容易实现:

Live On Coliru

#include <boost/iterator/iterator_adaptor.hpp>
#include <type_traits>

template<std::size_t N,typename Iterator>
class nth_iterator:
  public boost::iterator_adaptor<
    nth_iterator<N,Iterator>,Iterator,
    std::remove_reference_t<decltype((*std::declval<Iterator>())[N])>
  >
{
public:
  nth_iterator()=default;
  nth_iterator(const Iterator& it):nth_iterator::iterator_adaptor_{it}{}
  nth_iterator(const nth_iterator&)=default;
  nth_iterator& operator=(const nth_iterator&)=default;

private:
  friend class boost::iterator_core_access;

  decltype(auto) dereference()const
  {
    return (*this->base_reference())[N];
  }
};

template<std::size_t N,typename Iterator>
auto nth(Iterator it)
{
  return nth_iterator<N,Iterator>(it);
}

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
  std::vector<std::vector<int>> vec{{1,3,2}, {4,1,10}, {3,3,3}, {9,8,7}};

  auto print_vec=[&]{
    std::cout<<"{";
    const char* delim1="";
    for(auto&& x:vec){
      std::cout<<delim1<<"{";
      delim1=", ";
      const char* delim2="";
      for(auto&& y:x){
        std::cout<<delim2<<y;
        delim2=",";
      }
      std::cout<<"}";
    }
    std::cout<<"}\n";
  };

  print_vec();
  std::sort(nth<2>(vec.begin()),nth<2>(vec.end()));
  print_vec();  
}

输出

{{1,3,2}, {4,1,10}, {3,3,3}, {9,8,7}}
{{1,3,2}, {4,1,3}, {3,3,7}, {9,8,10}}

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 2023-01-11
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2011-07-11
    相关资源
    最近更新 更多