簡體   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