C ++ метод сортировки - PullRequest
       32

C ++ метод сортировки

1 голос
/ 27 апреля 2010

Я хочу отсортировать вектор с помощью std :: sort, но мой метод sort является статическим методом класса, и я хочу вызвать std :: sort вне его, но, похоже, это затрудняет его выполнение.

По классу:

static int CompareIt(void *sol1, void *sol2) { ... }

std :: sort call:

sort(distanceList.at(q).begin(), 
     distanceList.at(q).end(), 
     &DistanceNodeComparator::CompareIt);

Разве нельзя так поступить?

Ответы [ 5 ]

4 голосов
/ 27 апреля 2010

std::sort принимает компаратор, который принимает значение типа, хранящегося в коллекции, и возвращает bool. Как правило, он должен реализовывать некоторое понятие <. Например, если у ваших элементов distanceList есть коллекции целых чисел (полагаю, что нет, но для примера):

static bool CompareIt(int sol1, int sol2) { ... }

И, конечно, вам нужно предоставить компаратор, только если еще нет оператора <, который бы подходил для вашего сценария.

1 голос
/ 27 апреля 2010

Функция сравнения, которую вы предоставили, имеет сигнатуру, необходимую для qsort, которая является функцией сортировки, предоставленной C до появления C ++. sort требует совершенно другой функции.

Например, если ваше объявление distanceList равно std::vector<DistanceNode>, ваша функция будет выглядеть так:

static bool CompareIt(const DistanceNode &sol1, const DistanceNode &sol2)
{
    return sol1.key < sol2.key;
}

Обратите внимание, что сортировка std::list со стандартным алгоритмом sort неэффективна, поэтому list предоставляет свою собственную sort функцию-член.

1 голос
/ 27 апреля 2010

Это должен быть логический метод (по умолчанию для сравнения значений сортировка использует оператор <())

0 голосов
/ 27 апреля 2010

Как уже упоминалось, требуется логический тип возврата . Вот пример, который работает:

#include "stdafx.h"
#include <vector>
#include <algorithm>

using namespace std;

class MyClass
{
public:
    static bool CompareIt(const void *a1, const void *a2)
    {
        return a1 < a2;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{

    // Create a vector that contains elements of type MyData
    vector<void*> myvector;

    // Add data to the vector
    myvector.push_back((void*)0x00000005);
    myvector.push_back((void*)0x00000001);

    // Sort the vector
    std::sort(myvector.begin(), myvector.end(), MyClass::CompareIt);

    // Display some results
    for( int i = 0; i < myvector.size(); i++ )
    {
        printf("%d = 0x%08X\n", i, myvector[i] );
    }

    return 0;
}

[Редактировать] Обновлен код выше, чтобы сделать его немного проще. Я не предполагаю, что это хороший код, но, не зная больше о реальной реализации OP, сложно привести лучший пример!

0 голосов
/ 27 апреля 2010

Во-первых, тип возвращаемого значения должен быть bool. На самом деле требуется только, чтобы тип возвращаемого значения был назначен на bool, что int. Но тот факт, что вы возвращаете int, предполагает, что вы могли бы написать трехсторонний компаратор вместо строгого слабого порядка, требуемого std :: sort.

Ваша функция CompareIt принимает два void* указателя в качестве параметров. Является ли distanceList.at(q) vector<void*> (или вектором чего-то, что можно преобразовать в void*)? Если нет, то входные данные компаратора также неверны. Использование void* с алгоритмами также предполагает, что вы делаете что-то не так, потому что большая часть общего программирования заключается в том, что вам не нужны непрозрачные указатели, которые впоследствии возвращаются к своему первоначальному типу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...