3

我想知道是否可以使用 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)

请指教。

4

6 回答 6

7

根据我对您的问题的理解,您想将odd数字分开even。如果是这样,std::partition就会这样做。

如果您想按升序值和单独oddeven数字进行排序,我会使用类似于这段代码的东西(不过,您必须弄清楚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参数

于 2012-11-16T13:30:33.467 回答
5

为此,您应该使用std::partition而不是std::sort

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

对于排序,您通常希望排序基于任意两个元素的相对顺序。在这种情况下,您只想根据元素的固有属性对输入进行分区。两种情况都可以归结为另一种情况,但采用直接方法总是更容易一些。

于 2012-11-16T12:48:50.200 回答
1

如果您查看参考资料,std::sort您会发现它用于比较的函数应该采用两个参数进行比较。所以你的代码根本不起作用。

我建议您改为迭代向量,将偶数值排序到一个临时向量中,将奇数值排序到另一个临时向量中。然后你清除实际的向量,并按照你喜欢的顺序附加两个临时向量。

于 2012-11-16T12:42:53.213 回答
1

您可以编写一个比较函数,例如

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

然后您可以将其用作std::sort.

于 2012-11-16T12:44:10.133 回答
0

在 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;
        }
    }
于 2012-12-20T22:26:54.383 回答
0

问题是您可以使用两个功能。

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

我希望它有助于理解。

于 2016-02-26T16:48:18.043 回答