Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 二维向量迭代器_C++_Stl_Vector_Iterator - Fatal编程技术网

C++ 二维向量迭代器

C++ 二维向量迭代器,c++,stl,vector,iterator,C++,Stl,Vector,Iterator,如何为2d向量(向量向量的向量)创建迭代器?假设您指的是STL迭代器和实现通用2d对象数组的自定义容器,这是不可能的。STL迭代器仅支持递增和递减(即“下一个”和“上一个”)操作,其中通过2D集的运动需要四个这样的原语(例如左/右/上/下等)。这些比喻不相符 你想做什么?虽然你的问题不是很清楚,但我假设你指的是二维向量,也就是向量向量: vector< vector<int> > vvi; vectorvvi; 然后需要使用两个迭代器来遍历它,第一个是“行”的迭代器,

如何为2d向量(向量向量的向量)创建迭代器?

假设您指的是STL迭代器和实现通用2d对象数组的自定义容器,这是不可能的。STL迭代器仅支持递增和递减(即“下一个”和“上一个”)操作,其中通过2D集的运动需要四个这样的原语(例如左/右/上/下等)。这些比喻不相符

你想做什么?

虽然你的问题不是很清楚,但我假设你指的是二维向量,也就是向量向量:

vector< vector<int> > vvi;
vectorvvi;
然后需要使用两个迭代器来遍历它,第一个是“行”的迭代器,第二个是该“行”中“列”的迭代器:

//假设您有一个“2D”向量vvi(int的向量的向量)
向量<向量>::迭代器行;
向量::迭代器列;
for(row=vvi.begin();row!=vvi.end();row++){
对于(col=行->开始();col!=行->结束();col++){
//做些事情。。。
}
}

假设您指的是向量的向量,并且您已经记住了
std::vector
,没有内置的方法来实现这一点,因为迭代器只支持向前和向后移动的递增和递减操作

2D向量是矩阵,因此需要两种迭代器类型:行迭代器和列迭代器。行迭代器将在矩阵中“向上”和“向下”移动,而列迭代器将在矩阵中“向左”和“向右”移动


您必须自己实现这些迭代器类,这不一定是一件小事。当然,除非您只想迭代矩阵中的每个插槽,在这种情况下,使用索引变量
i
j
的双for循环就可以正常工作。根据您的需要(您的帖子在这里有点缺少内容),您可能希望使用boost::numeric::ublas::matrix,这是boost线性代数库中的矩阵类。该矩阵类具有内置的行和列迭代器,这使得在矩阵上进行迭代通常很容易。

您可以使用range for语句来迭代二维向量中的所有元素

vector< vector<int> > vec;

另一种解释这个问题的方法是,你需要一个1D迭代器在一个
向量上
例如,将它馈送给
for_each()
或其他一些算法

您可以这样做:

#include <iostream>

#include <iterator>
#include <vector>
#include <algorithm>

// An iterator over a vector of vectors.
template<typename T>
class vv_iterator : public std::iterator<std::bidirectional_iterator_tag, T>{
public:

  static vv_iterator<T> begin(std::vector<std::vector<T>>& vv) {
    return vv_iterator(&vv, 0, 0);
  }
  static vv_iterator<T> end(std::vector<std::vector<T>>& vv) {
    return vv_iterator(&vv, vv.size(), 0);
  }

  vv_iterator() = default;
  // ++prefix operator
  vv_iterator& operator++()
  {
    // If we haven't reached the end of this sub-vector.
    if (idxInner + 1 < (*vv)[idxOuter].size())
    {
      // Go to the next element.
      ++idxInner;
    }
    else
    {
      // Otherwise skip to the next sub-vector, and keep skipping over empty
      // ones until we reach a non-empty one or the end.
      do
      {
        ++idxOuter;
      } while (idxOuter < (*vv).size() && (*vv)[idxOuter].empty());

      // Go to the start of this vector.
      idxInner = 0;
    }
    return *this;
  }
  // --prefix operator
  vv_iterator& operator--()
  {
    // If we haven't reached the start of this sub-vector.
    if (idxInner > 0)
    {
      // Go to the previous element.
      --idxInner;
    }
    else
    {
      // Otherwise skip to the previous sub-vector, and keep skipping over empty
      // ones until we reach a non-empty one.
      do
      {
        --idxOuter;
      } while ((*vv)[idxOuter].empty());

      // Go to the end of this vector.
      idxInner = (*vv)[idxOuter].size() - 1;
    }
    return *this;
  }
  // postfix++ operator
  vv_iterator operator++(int)
  {
    T retval = *this;
    ++(*this);
    return retval;
  }
  // postfix-- operator
  vv_iterator operator--(int)
  {
    T retval = *this;
    --(*this);
    return retval;
  }
  bool operator==(const vv_iterator& other) const
  {
    return other.vv == vv && other.idxOuter == idxOuter && other.idxInner == idxInner;
  }
  bool operator!=(const vv_iterator &other) const
  {
    return !(*this == other);
  }
  const T& operator*() const
  {
    return *this;
  }
  T& operator*()
  {
    return (*vv)[idxOuter][idxInner];
  }
  const T& operator->() const
  {
    return *this;
  }
  T& operator->()
  {
    return *this;
  }

private:
  vv_iterator(std::vector<std::vector<T>>* _vv,
              std::size_t _idxOuter,
              std::size_t _idxInner)
    : vv(_vv), idxOuter(_idxOuter), idxInner(_idxInner) {}

  std::vector<std::vector<int>>* vv = nullptr;
  std::size_t idxOuter = 0;
  std::size_t idxInner = 0;
};



int main()
{
    std::vector<std::vector<int>> a = {{3, 5, 2, 6}, {-1, -4, -3, -5}, {100}, {-100}};
    std::reverse(vv_iterator<int>::begin(a), vv_iterator<int>::end(a));
    for (const auto& v : a)
    {
        std::cout << "{ ";
        for (auto i : v)
           std::cout << i << " ";
        std::cout << "}\n";
    }
}

注意这不适用于
std::sort()
,因为这需要一个随机访问迭代器。您可以将其设置为随机访问迭代器,但必须在开始时扫描向量,以便可以在恒定时间内从平面索引映射到
idxOuter
idxInner
。不完全是琐碎的,但也不难。

假设你有这样一个向量:-

向量向量{{1,2,3},{4,5,6},{7,8,9}

现在将迭代器用于二维向量:-

for(auto i=vect.begin();ibegin();jend();j++)

cout在这种情况下,您可以使用auto关键字:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int main() {
    // your code goes here
    vector<vector<int>>v;

    for(int i=0;i<5;i++)
    {
        vector<int> x={1,2,3,4,5};
        v.push_back(x);
    }
    cout<<"-------------------------------------------"<<endl;
    cout<<"Print without iterator"<<endl;
    cout<<"-------------------------------------------"<<endl;
    for(int i=0;i<5;i++)
    {
        vector<int> y=v[i];
        for(int j=0;j<y.size();j++)
        {
            cout<<y[j]<<" ";
        }
        cout<<endl;
    }
    cout<<"-------------------------------------------"<<endl;
    cout<<"Print with iterator"<<endl;
    cout<<"-------------------------------------------"<<endl;
    for(auto iterator=v.begin();iterator!=v.end();iterator++)
    {
        vector<int> y=*iterator;
        for(auto itr=y.begin();itr!=y.end();itr++)
        {
            cout<<*itr<<" ";
        }
        cout<<endl;
    }
    return 0;
}
#包括
#包括
使用名称空间std;
int main(){
//你的密码在这里
向量;

对于(inti=0;i自2020年以来,我将发布一个更新的、简单的方法。在编写时适用于c++11及以上版本。 请参见以下示例,其中迭代2D vector(vector of vector)的元素(此处:元组)与另一个值(string query)进行比较,然后函数返回第一个匹配的元素,或指示“未找到”

元组查找串行数据(矢量和串行、,
字符串查询)
{
用于(自动和输入:串行)
{
对于(auto&j:i)
{
if(get(j).compare(query)==0)返回j;
}
}

可能无法更好地描述问题的上下文?更具体地说:2d向量的声明是什么?您希望迭代的顺序是什么?您希望如何使用迭代器?很抱歉,我的问题不太清楚,但这正是我想要的。尽管我在这段代码中遇到编译器错误:无法从“std:”转换:_对于(row=vvi.begin();row!=vvi.end();row++),从“向量迭代器”到“int”的向量{总是使用预增量运算符。使用向量很可能在使用向量时是不重要的,但是进入一个坏习惯。如果它是++C而不是C++,生命会更加清晰。如果列中只有2个元素。我们在行一遍时如何访问它们。@ Anoop Sorry,我不明白你的问题?你是MEA吗?n您需要访问
*col[0]
*col[1]
?正是我的意思,2D向量矩阵带有(现在我知道有两个)迭代器。我想问题很清楚:(…无论如何,我对向量很陌生,我必须在这项工作中使用它们。现在另一个问题是我在上面的评论中发布的错误(格式化是狗屎).无法将值分配给第一个(行)迭代器,因为类型不匹配。我一直在寻找你对这个问题的准确解释。我说的对吗,这只是非常量迭代器,需要为
常量迭代器
编写第二个类?你存储索引而不是向量迭代器有什么具体原因吗?顺便说一句,我花了一段时间才理解还有这个例子,因为输出使用“普通”迭代器,而1D迭代器的用法在这一看似无辜的
reverse
行中有点隐藏。是的,在我的实际代码中,我有一个
const_迭代器版本。它或多或少是一个复制/粘贴,删除了非const成员(我找不到避免复制/粘贴的方法)很好,我想没有理由不使用向量迭代器。这可能更好,我只是没想过而已。
#include <iostream>

#include <iterator>
#include <vector>
#include <algorithm>

// An iterator over a vector of vectors.
template<typename T>
class vv_iterator : public std::iterator<std::bidirectional_iterator_tag, T>{
public:

  static vv_iterator<T> begin(std::vector<std::vector<T>>& vv) {
    return vv_iterator(&vv, 0, 0);
  }
  static vv_iterator<T> end(std::vector<std::vector<T>>& vv) {
    return vv_iterator(&vv, vv.size(), 0);
  }

  vv_iterator() = default;
  // ++prefix operator
  vv_iterator& operator++()
  {
    // If we haven't reached the end of this sub-vector.
    if (idxInner + 1 < (*vv)[idxOuter].size())
    {
      // Go to the next element.
      ++idxInner;
    }
    else
    {
      // Otherwise skip to the next sub-vector, and keep skipping over empty
      // ones until we reach a non-empty one or the end.
      do
      {
        ++idxOuter;
      } while (idxOuter < (*vv).size() && (*vv)[idxOuter].empty());

      // Go to the start of this vector.
      idxInner = 0;
    }
    return *this;
  }
  // --prefix operator
  vv_iterator& operator--()
  {
    // If we haven't reached the start of this sub-vector.
    if (idxInner > 0)
    {
      // Go to the previous element.
      --idxInner;
    }
    else
    {
      // Otherwise skip to the previous sub-vector, and keep skipping over empty
      // ones until we reach a non-empty one.
      do
      {
        --idxOuter;
      } while ((*vv)[idxOuter].empty());

      // Go to the end of this vector.
      idxInner = (*vv)[idxOuter].size() - 1;
    }
    return *this;
  }
  // postfix++ operator
  vv_iterator operator++(int)
  {
    T retval = *this;
    ++(*this);
    return retval;
  }
  // postfix-- operator
  vv_iterator operator--(int)
  {
    T retval = *this;
    --(*this);
    return retval;
  }
  bool operator==(const vv_iterator& other) const
  {
    return other.vv == vv && other.idxOuter == idxOuter && other.idxInner == idxInner;
  }
  bool operator!=(const vv_iterator &other) const
  {
    return !(*this == other);
  }
  const T& operator*() const
  {
    return *this;
  }
  T& operator*()
  {
    return (*vv)[idxOuter][idxInner];
  }
  const T& operator->() const
  {
    return *this;
  }
  T& operator->()
  {
    return *this;
  }

private:
  vv_iterator(std::vector<std::vector<T>>* _vv,
              std::size_t _idxOuter,
              std::size_t _idxInner)
    : vv(_vv), idxOuter(_idxOuter), idxInner(_idxInner) {}

  std::vector<std::vector<int>>* vv = nullptr;
  std::size_t idxOuter = 0;
  std::size_t idxInner = 0;
};



int main()
{
    std::vector<std::vector<int>> a = {{3, 5, 2, 6}, {-1, -4, -3, -5}, {100}, {-100}};
    std::reverse(vv_iterator<int>::begin(a), vv_iterator<int>::end(a));
    for (const auto& v : a)
    {
        std::cout << "{ ";
        for (auto i : v)
           std::cout << i << " ";
        std::cout << "}\n";
    }
}
{ -100 100 -5 -3 }
{ -4 -1 6 2 }
{ 5 }
{ 3 }
 for(auto i = vect.begin() ; i<vect.end() ; i++)
  {
     for(auto j = i->begin() ; j<i->end() ; j++)
        cout << *j <<" ";
     cout <<"\n";  
     //similarly you can do other things
  }
 for(auto i : vect)
  {
     for(auto j : i)
        cout << j <<" ";
     cout << "\n";
//similarly you can do other things also.
  }
#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int main() {
    // your code goes here
    vector<vector<int>>v;

    for(int i=0;i<5;i++)
    {
        vector<int> x={1,2,3,4,5};
        v.push_back(x);
    }
    cout<<"-------------------------------------------"<<endl;
    cout<<"Print without iterator"<<endl;
    cout<<"-------------------------------------------"<<endl;
    for(int i=0;i<5;i++)
    {
        vector<int> y=v[i];
        for(int j=0;j<y.size();j++)
        {
            cout<<y[j]<<" ";
        }
        cout<<endl;
    }
    cout<<"-------------------------------------------"<<endl;
    cout<<"Print with iterator"<<endl;
    cout<<"-------------------------------------------"<<endl;
    for(auto iterator=v.begin();iterator!=v.end();iterator++)
    {
        vector<int> y=*iterator;
        for(auto itr=y.begin();itr!=y.end();itr++)
        {
            cout<<*itr<<" ";
        }
        cout<<endl;
    }
    return 0;
}
tuple<string, size_t> find_serial_data( vector <vector <tuple <string, size_t>>> &serial,
                                        string query)
{
    for (auto& i : serial)
    {
        for (auto& j : i)
        {
            if ( get<0>(j).compare(query) == 0) return j;
        }
    }
    cout << "\n Not found";
    return make_tuple( "", 0);
}
string find_serial_data( vector <vector <string> > &serials,
                                        string query)
{
    for (auto& i : serials)
    {
        for (auto& j : i)
        {
            if ( j.compare(query) == 0) return j;
        }
    }
    cout << "\n Not found";
    return  "";
}