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

时间:2014-08-13 00:38:24

标签: c++ iterator selection-sort

我是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;
}

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

Swap is already a defined function.

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

如果您将函数命名为myswap并调用myswap而不是swap,则可能会看到编译器错误消息。查看my question on the subject

相反,如果您使用:

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