Сортировка по четным и нечетным номерам

Вопрос:Я хотел бы знать, возможно ли сортировать число четным или нечетным с помощью функции std:: sort. У меня есть следующие коды, но я не уверен, как реализовать в std:: sort inline bool isEven(const Point n) { return n.getX()%2==0; } Правильно ли это. vector c; std::sort(c.begin(),c.end(),isEven) Пожалуйста, совет. Лучший ответ: Из того, что я понимаю по

Вопрос:

Я хотел бы знать, возможно ли сортировать число четным или нечетным с помощью функции std:: sort.

У меня есть следующие коды, но я не уверен, как реализовать в std:: sort

inline bool isEven(const Point n) { return n.getX()%2==0; }

Правильно ли это.

vector<Point> c; std::sort(c.begin(),c.end(),isEven)

Пожалуйста, совет.

Лучший ответ:

Из того, что я понимаю по вашему вопросу, вы хотите отделить числа odd и even. Если это произойдет, std::partition сделает именно это.

Если вы хотите отсортировать по восходящим значениям и отдельным номерам odd и even, я бы использовал нечто похожее на этот фрагмент кода (все же вам нужно будет выяснить, какой компонент вашего Point вы хотите для сортировки)

bool sortByEven(const int& left, const int& right) { if(left & 1 && right & 1) // both are odd { return left < right; } else if(left & 1) // left is odd { return false; } else if(right & 1) // right is odd { return true; } // both are even return left < right; }

Эта функция может использоваться с std::sort, здесь краткий пример:

std::vector<int> numbers; numbers.push_back(-1); numbers.push_back(5); numbers.push_back(12); numbers.push_back(7); numbers.push_back(-31); numbers.push_back(-20); numbers.push_back(0); numbers.push_back(41); numbers.push_back(16); std::sort(numbers.begin(), numbers.end(), sortByEven);

Выдает следующий результат:

-20 0 12 16 -31 -1 5 7 41

Для других типов просто измените int или сделайте его template параметром

Ответ №1

Для этого вы должны использовать std::partition вместо std::sort

vector<Point> c; std::partition(c.begin(),c.end(),isEven)

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

Ответ №2

Если вы посмотрите на ссылку std::sort, вы увидите, что функция, которую она использует для сравнения, должна принимать два аргумента, которые она должна сравнивать, Таким образом, ваш код не будет работать вообще.

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

Ответ №3

Вы можете написать функцию сравнения, например

bool evenOddLess( Point const& a, Point const& b ) { return (isEven( a ) < isEven( b )); }

Затем вы можете использовать это как третий аргумент для std::sort.

Ответ №4

В С# это еще проще:

class Program { static void Main() { int[] numbers = { 1, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14 }; //using delegate Array.Sort (numbers, (x, y) => x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1); Array.ForEach(numbers, x => Console.Write(x)); Console.WriteLine(«»); //using custom comparer CustomComparer comparer = new CustomComparer(); Array.Sort(numbers, comparer); Array.ForEach(numbers, x => Console.Write(x)); Console.WriteLine(«»); //using lambda int[] items = numbers.OrderBy(x => x % 2 == 0).ThenBy(x => x % 2).ToArray(); Console.WriteLine(«»); Array.ForEach(items, x => Console.Write(x)); } public int Compare(int x, int y) { return x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1; } } public class CustomComparer : IComparer<int> { int IComparer<int>.Compare(int x, int y) { return x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1; } } Ответ №5

Уловка состоит в том, что есть две функции, которые вы можете использовать.

template< class BidirectionalIterator, class UnaryPredicate > BidirectionalIterator partition( BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate p ); template< class BidirectionalIterator, class UnaryPredicate > BidirectionalIterator stable_partition( BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate p );

Функции раздел() и stable_partition() реорганизовывать элементов коллекции таким образом, чтобы все элементы для который предикат p возвращает true, будет предшествовать всем тем, для который p возвращает false. Это означает, что элементы будут разделен на два диапазона:

• [first, return_value)

• [return_value, last)

где return_value – итератор, возвращаемый любой из функций. Последовательность элементов в результирующих группах partition() и stable_partition() отличаются.

partition() не гарантирует любой конкретный порядок в пределах диапазоны.

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

Вот пример кода:

#include <iostream> #include <algorithm> #include <vector> using namespace std; bool IsOdd(int i) { return (i & 1); //use !(i & 1); if you want to place even elements first in the vector } int main() { vector<int> v; // set some values and shuffle them: for (int i = 1; i<10; ++i) v.push_back(i); random_shuffle(v.begin(), v.end()); cout << «All elements:»; for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) cout << ‘ ‘ << *it; cout << endl; //sort the vector cout << «Sorted vector:»; sort(v.begin(), v.end()); for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) cout << ‘ ‘ << *it; cout << endl; //change to partition and see the difference vector<int>::iterator bound = stable_partition(v.begin(), v.end(), IsOdd); // print content: cout << «odd elements:»; for (std::vector<int>::iterator it = v.begin(); it != bound; ++it) cout << ‘ ‘ << *it; cout << endl; cout << «even elements:»; for (vector<int>::iterator it = bound; it != v.end(); ++it) cout << ‘ ‘ << *it; cout << endl; cout << «Sorted odd-even vector:»; for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) cout << ‘ ‘ << *it; cout << endl; return 0; }

Вывод:

All elements: 5 6 2 1 9 4 7 8 3 Sorted vector: 1 2 3 4 5 6 7 8 9 odd elements: 1 3 5 7 9 even elements: 2 4 6 8 Sorted odd-even vector: 1 3 5 7 9 2 4 6 8

Я надеюсь, что это поможет понять.

Оцените статью
Добавить комментарий