Sort by Even and Odd numbers

前端 未结 6 1020
故里飘歌
故里飘歌 2021-01-20 16:45

I would like to know is it possible to sort number by even or odd using the std::sort function.

I have the following codes but i am not sure how to implement in the

相关标签:
6条回答
  • 2021-01-20 17:02

    If you look at a reference for std::sort you will see that the function it uses to compare should take two arguments that it should compare. So your code will not work at all.

    I recommend you instead iterate over the vector, sorting out even values into one temporary vector, and the odd values into another temporary vector. Then you clear the actual vector, and append the two temporary vectors in the order you like.

    0 讨论(0)
  • 2021-01-20 17:02

    You can write a comparison function like

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

    Then you can use that as third argument to std::sort.

    0 讨论(0)
  • 2021-01-20 17:04

    For this, you should use std::partition instead of std::sort

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

    With sorting, you typically want the sorting to be based on the relative order of any two elements. In this case, you just want to partition your input based on an inherent property of your elements. Both cases can be reduced to the other, but it is always a little easier to take the direct approach.

    0 讨论(0)
  • 2021-01-20 17:10

    The catch is that there are two functions you can use.

    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 );
    

    The functions partition() and stable_partition() reorganize elements of the collection in such a way that all elements for which predicate p returns true will precede all those for which p returns false. It means that the elements will be divided into two ranges:

    • [first, return_value)

    • [return_value, last)

    where return_value is the iterator returned by either of functions. The sequence of elements in the resulting groups is where partition() and stable_partition() differ.

    partition() does not guarantee any particular order within the ranges.

    stable_partition() will keep a relative order of elements before the split. It means that if there are two elements a and b, and a precedes b, and if they both belong to the same group after the split, element a will still precede element b.

    Here is a sample code:

    #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;
    }
    

    Output:

    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
    

    I hope it helps for understanding.

    0 讨论(0)
  • 2021-01-20 17:18

    From what I understand of your question, you want to separate odd and even numbers. If that's the case, std::partition will do just that.

    If you want to sort by ascending values AND separate odd and even numbers, I would use something similar to this piece of code (still, you will have to figure out which component of your Point you want to sort on)

    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;
    }
    

    This function can be used with std::sort, here's a short example:

    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);
    

    Will give you the following output:

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

    For other types simply change the int or make it a template parameter

    0 讨论(0)
  • 2021-01-20 17:21

    In C# it is even simpler:

     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;
            }
        }
    
    0 讨论(0)
提交回复
热议问题