Как я могу определить сортировку "ничего не делать"? - PullRequest
5 голосов
/ 23 февраля 2010

Я работаю в системе, где мне нужно иметь возможность сортировать вектор по заданному предикату, который мои классы не должны контролировать.По сути, я передаю им производный класс, и они слепо сортируют его.

Как одна из «восхитительных причуд», одним из шаблонов сортировки является порядок входа.Вот что у меня так далеко.

struct Strategy
{
   virtual bool operator()(const Loan& lhs, const Loan& rhs) const = 0;
};

struct strategyA : public Strategy
{
   bool operator()(const Loan& lhs, const Loan& rhs) const
   {
      return true;
   }
};

struct strategyB : public Strategy
{
   bool operator()(const Loan& lhs, const Loan& rhs) const
   {
      return lhs.getID() > rhs.getID();
   }
};

struct strategyC : public Strategy
{
   bool operator()(const Loan& lhs, const Loan& rhs) const
   {
      return lhs.getFee() > rhs.getFee();
   }
};

Очевидно, что стратегия A рефлексивна, ее нельзя использовать, и если я установлю ее в false, она будет относиться ко всем как к равным, и я могупоцелуй мои данные до свидания.

Так вот мой вопрос.Есть ли способ определения функции предиката для сортировки вектора, который ничего не изменит?

Я знаю, что, возможно, самое простое решение - это добавить переменную порядка входа в класс Loan или стать партнером по нему.с одним в паре.В качестве альтернативы я мог бы передать параметр с помощью предиката, который сообщает сортировщику, использовать его или нет.

Ответы [ 5 ]

7 голосов
/ 23 февраля 2010

Есть ли способ определения функции предиката для сортировки вектора, который ничего не изменит?

Это зависит от алгоритма. Если ваша сортировка - стабильная сортировка , порядок "равных" элементов не будет изменен (что не определено для нестабильных сортировок).

Рассмотрите возможность использования std::stable_sort.

2 голосов
/ 23 февраля 2010

Лично я думаю, что у вашего класса стратегии должен быть метод "сортировки". Таким образом, он может либо вызвать std :: sort, либо нет, как считает нужным. Будь то , а также как это станет частью стратегии сортировки.

Darios stable_sort ответ очень хорош, если вы можете его использовать.

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

Для сравнения возможно сохранить отображение текущей позиции в исходную позицию, но много работы. В идеале логика должна быть встроена в алгоритм сортировки, а не только в сравнение, и именно так работает stable_sort.

Другая проблема - в зависимости от контейнера - порядок (скажем) адресов элементов не всегда порядок элементов.

1 голос
/ 23 февраля 2010

Нет функции сортировки, которая бы сохраняла порядок элементов, основываясь только на значениях элементов. Вам необходимо предоставить больше информации вашему Strategy, если это возможно.

1 голос
/ 23 февраля 2010

Если это просто вектор, о котором вы говорите, возможно, вам не помешает предоставить интерфейс, который определяет, следует вам сортировать или нет. векторы не являются упорядоченным контейнером, поэтому вам необходимо явно отсортировать их. Просто не сортируйте их вообще.

0 голосов
/ 23 февраля 2010

Другой подход может заключаться в переносе семантики ваших данных в контейнер. Рассмотрите возможность использования boost :: multi_index для разных способов доступа и упорядочения одних и тех же данных:

http://www.boost.org/doc/libs/1_42_0/libs/multi_index/doc/index.html

...