Использовать std :: vector :: iterator для изменения значений, хранящихся в 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;
}

1

Решение

Проблема, с которой вы сталкиваетесь при обмене значениями, на которые указывают итераторы, вызвана тем, что компилятор подхватывает std::swap с помощью ADL. 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;
}

Выход


Тестирование myswap ()
Итераторы значений указывают на перед свопом.
1 3
Значения итераторов указывают после перестановки.
3 1
Вектор после свопа.
3 2 1 4 5 6
0

Другие решения

Да, это возможно. Учитывая итератор iter, *iter может быть назначено как обычное lvalue для изменения основного контейнера, например:

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

Это возможно. И вот хитрость, чтобы сделать вашу жизнь проще.

Своп уже определенная функция.

добавлять #include <utility> и вы получите swap бесплатно. Многие объекты C ++ определяют специализации подкачки. Например, std::vector реализует обмен между двумя векторами, просто меняя указатели.

Для вашего кода вы можете удалить определение swap и использовать swap(*pos, *minPos)

1

Мне нужно было назвать свой код: будучи совсем новым новичком, я не осознавал std::swap(iter, iter) уже существует, и был призван — а не мой swap функция.

Тем не менее, после того, как я поместил пространство имен в свой код, ответ jwodder доказал свою эффективность: используя *iter скорее, чем iterмой код скомпилирован и вектор был правильно изменен swap,

0
По вопросам рекламы [email protected]