我想知道是否可以使用 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
参数
为此,您应该使用std::partition
而不是std::sort
vector<Point> c;
std::partition(c.begin(),c.end(),isEven)
对于排序,您通常希望排序基于任意两个元素的相对顺序。在这种情况下,您只想根据元素的固有属性对输入进行分区。两种情况都可以归结为另一种情况,但采用直接方法总是更容易一些。
如果您查看参考资料,std::sort
您会发现它用于比较的函数应该采用两个参数进行比较。所以你的代码根本不起作用。
我建议您改为迭代向量,将偶数值排序到一个临时向量中,将奇数值排序到另一个临时向量中。然后你清除实际的向量,并按照你喜欢的顺序附加两个临时向量。
您可以编写一个比较函数,例如
bool evenOddLess( Point const& a, Point const& b )
{ return (isEven( a ) < isEven( b )); }
然后您可以将其用作std::sort
.
在 C# 中,它甚至更简单:
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;
}
}
问题是您可以使用两个功能。
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 );
函数partition()和stable_partition()重新组织集合的元素,使得谓词 p 返回true的所有元素都在p 返回false的所有元素之前。这意味着元素将分为两个范围:
• [first, return_value)
• [return_value,最后一个)
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
我希望它有助于理解。