vector<vector<T>> 中每个向量的第 n 个元素的迭代器

Posted

技术标签:

【中文标题】vector<vector<T>> 中每个向量的第 n 个元素的迭代器【英文标题】:Iterator on nth element of each vector in vector<vector<T>> 【发布时间】: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 标准库) 【参考方案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>> vec1,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

【讨论】:

以上是关于vector<vector<T>> 中每个向量的第 n 个元素的迭代器的主要内容,如果未能解决你的问题,请参考以下文章

将 stl 算法应用于多维向量 (vector<vector<T> >)

vector<vector<T>> 中每个向量的第 n 个元素的迭代器

在 std::vector<T> 和 std::vector<unique_ptr<T>> 上均匀迭代

如何构造可以替换 typedef vector<vector<T>> 类型的类

std::vector<std::array<T, N>> 或 std::array<std::vector<T>,N> 类型的数组如何存储在内存中?

如何桥接 JavaScript(参差不齐)数组和 std::vector<std::vector<T>> 对象?