繁体   English   中英

使用std :: vector :: iterator来改变存储在std :: vector中的值?

[英]Use std::vector::iterator to alter values stored in std::vector?

我是C ++的新手,我正在尝试将选择排序算法作为练习来实现。

我已经尝试将最左边的内存位置的值与向量的未排序部分的最小内存位置中的值进行交换。

(参见下面的代码。)

是否可以使用std::vector::iterator来改变它所属的向量中包含的值?

#include <vector>
#include <stdlib.h>
#include <time.h>
#include <iostream>

using namespace std;

template<typename T>
ostream& operator<<( ostream& out, vector<T> thisVector ) {

  for( size_t i = 0, choke = thisVector.size(); i < choke; i++ )
    out << thisVector[ i ] << " ";

  return out;
}

template<typename T>
typename vector<T>::iterator get_minimum( vector<T>& thisVector, typename vector<T>::iterator pos, typename vector<T>::iterator end ) {

  T min = *pos;
  typename vector<T>::iterator minPos;

  while ( pos != end ) {
    if ( *pos < min ) {
      min = *pos;
      minPos = pos;
    }
    pos++;
  }
  return minPos;
}

template<typename T>
void swap( typename vector<T>::iterator pos, typename vector<T>::iterator& minPos ) {

  T temp = *pos;

  // I was hoping the following two lines would modify the vector passed to selection_sort
  pos = *minPos;
  minPos = temp;
  return;
}

template<typename T>
void selection_sort( vector<T>& thisVector, typename vector<T>::iterator pos ) {

  typename vector<T>::iterator end = thisVector.end();
  typename vector<T>::iterator minPos = get_minimum( thisVector, pos, end );
  cout << "Swap was given this " << *pos << " " << *minPos << endl;
  swap( pos, minPos );
  cout << "and returned this " << *pos << " " << *minPos << endl;
  return;
}

int main() {

  // initialize random seed
  srand (time(NULL));

  // Create data stub
  vector<int> myThing;
  do {
    myThing.push_back( rand() % 20 );
  } while ( myThing.size() <= 10 );

  cout << "Unsorted: " << myThing << endl;
  selection_sort( myThing, myThing.begin() );
  cout << "  Sorted: " << myThing << endl;

  return 0;
}

对的,这是可能的。 给定迭代器iter*iter可以像普通左值一样分配来修改底层容器,例如:

*iter = 5;  // The value in the container that `iter` points to is now 5.

有可能的。 这是让你的生活更轻松的一招。

交换已经是一个定义的函数。

添加#include <utility>免费获得swap 许多C ++对象定义交换特化。 例如, std::vector通过简单地交换指针来实现两个向量之间的交换。

对于您的代码,您可以删除交换的定义并使用swap(*pos, *minPos)

我需要将我的代码命名为:作为一个非常新的新手,我没有意识到std::swap(iter, iter)已经存在,并且被调用 - 而不是我的swap函数。

尽管如此,一旦我命名我的代码,jwodder的响应就证明了这一点:通过使用*iter而不是iter ,我的代码被编译并且向量被swap正确修改。

交换器指向的值所面临的问题是由编译器通过使用ADL获取std::swap这一事实引起的。 std::swap只是交换迭代器指向的位置,而不是迭代器指向的值。

如果将函数命名为myswap并调用myswap而不是swap ,则可能会看到编译器错误消息。 看看我关于这个问题的问题

相反,如果您使用:

template<typename Iterator>
void myswap(Iterator pos1,
            Iterator pos2)
{
   auto temp = *pos1;
   *pos1 = *pos2;
   *pos2 = temp;
}

一切都应该有效。 这是一个使用g ++ 4.8.2的工作程序。

#include <iostream>
#include <vector>
#include <iterator>

template<typename Iterator>
void myswap(Iterator pos1, Iterator pos2)
{
   auto temp = *pos1;
   *pos1 = *pos2;
   *pos2 = temp;
}

void testMyswap()
{
   std::cout << "\nTesting myswap()\n";
   std::vector<int> v{1, 2, 3, 4, 5, 6};

   std::vector<int>::iterator iter = v.begin();
   std::vector<int>::iterator temp = std::next(iter, 2);

   std::cout << "Values iterators point to before swap.\n";
   std::cout << *iter << " " << *temp << std::endl;
   myswap(iter, temp);
   std::cout << "Values iterators point to after swap.\n";
   std::cout << *iter << " " << *temp << std::endl;

   std::cout << "The vector after the swap.\n";
   for ( iter = v.begin(); iter != v.end(); ++iter )
   {
      std::cout << *iter << " ";
   }
   std::cout << std::endl;
}

int main()
{
   testMyswap();
   return 0;
}

产量

Testing myswap()
Values iterators point to before swap.
1 3
Values iterators point to after swap.
3 1
The vector after the swap.
3 2 1 4 5 6

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM