Проблемы понимания итераторов и перегрузки операторов в C ++ - PullRequest
0 голосов
/ 20 июля 2010

У нас есть пример класса, и я просто не понимаю.Я не совсем понимаю, как работает оператор () в этом случае, и все начинается с сортировки.Я посмотрел на вывод после запуска программы, и я не вижу, как эти значения получены.

sort indices array: 2 8 10 4 1 7 5 3 0 9 6 11
replay numbers array: 37 33 29 36 32 35 39 34 30 38 31 40
number array via indices 29 30 31 32 33 34 35 36 37 38 39 40

Я пытался найти функторы на этой доске, поскольку название - пример функтора, но, думаю, я не вижу, как функторы здесь играют.Любые мысли будут высоко оценены, так как я полностью потерян.Спасибо!

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

#include "IndexCompare.h"

using namespace std;

template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
     while (first != last) {
        *first++ = value++;
     }
}

const int MAX = 12;

int main() {
    int numbers[] = {37, 33, 29, 36, 32, 35, 39, 34, 30, 38, 31, 40};

    vector<int> vecNum(numbers, numbers + MAX);

    // Display original number array.
    cout << "--- initial numbers array ---" << endl;

    vector<int>::iterator iter = vecNum.begin();
    for (; iter != vecNum.end(); iter++ ) {
        cout << *iter << " ";
    }
    cout << "\n";

    vector<int> indices( vecNum.size() );

    // fill indices array
    cout << "\n--- invoke 'iota' on indices array ---";
    iota( indices.begin(), indices.end(), 0 );

    // Display original indices array.
    cout << "\n linear indices array: ";
    vector<int>::iterator iterIdx = indices.begin();
    for (; iterIdx != indices.end(); iterIdx++ ) {
        cout << *iterIdx << " ";
    }
    cout << "\n";

    // sort indices array
    cout << "\n--- invoke 'Sort' on indices based on number array ---";
    sort(indices.begin(), indices.end(),
          IndexCompare<vector<int>::iterator>(vecNum.begin(),vecNum.end()));

    // Display sorted indices array
    cout << "\n Sorted indices array: ";
    for (iterIdx = indices.begin(); iterIdx != indices.end(); iterIdx++ ) {
        cout << *iterIdx << " ";
    }
    cout << "\n";

    cout << "\n--- Run check on number array indexed normally ---";
    // Display original numbers array.
    cout << "\n replay numbers array: ";
    iter = vecNum.begin();
    for (; iter != vecNum.end(); iter++ ) {
        cout << *iter << " ";
    }
    cout << "\n";

    cout << "\n--- Run check on number array indexed with sorted indices ---";
    // Print original nums array indirectly through indices.
    cout << "\n number array via indices: ";
    for (int index = 0; index < vecNum.size(); index++ )
        cout << vecNum[indices[index]] << " ";
    cout << "\n";

    getchar();

    return 0;
}

// IndexCompare.h - interface for IndexCompare class template
#ifndef _INDEXCOMPARE_H_
#define _INDEXCOMPARE_H_
#pragma once

template <class random_iterator>
class IndexCompare {
public:
    IndexCompare(random_iterator begin, random_iterator end)
        : begin(begin), end(end) {}

    ~IndexCompare() {}

    bool operator() (unsigned int first, unsigned int second) {
            return (*(begin + first) < *(begin + second));

    }

private:
    random_iterator begin;
    random_iterator end;
};

#endif

1 Ответ

3 голосов
/ 20 июля 2010

Я не уверен, что смогу объяснить это правильно.Вот моя попытка:

(1).vector<int> indices( vecNum.size() );

Вы создаете вектор для хранения индексов для элементов в векторе vecNum.Очевидно, что количество элементов в этом векторе равно количеству элементов в vecNum.

(2).iota( indices.begin(), indices.end(), 0 );

Инициализация indices значениями от 0 - vecNum.size() - 1

(3).

sort(indices.begin(), indices.end(),
              IndexCompare<vector<int>::iterator>(vecNum.begin(),vecNum.end()));

Для каждого элемента в векторе indices вызывается функтор IndexCompare.Этот функтор в своем operator() получает значение из вектора vecNum, соответствующего данной позиции индекса.Таким образом, в основном вы сортируете вектор indices (не vecNum) на основе значений в vecNum.Следовательно, vecNum остается неизменным, а indices сортируется на основе значений из vecNum.

Чтобы сделать его более понятным (я надеюсь), начальное состояние вектора индексов будет выглядеть так: индексы= 0,1,2 и vecNum = 20,10,30

Теперь вы звоните std::sort со своим функтором.Таким образом, чтобы определить, является ли 0 меньше 1 sort, алгоритм будет использовать ваш функтор.Внутри функтора вы определяете, 0 <1, используя логику: vecNum [0] (то есть 20) <vecNum [1] (то есть 10).Таким образом, отсортированная позиция будет иметь индексы = 1,0,2. </p>

...