Move all odd positioned element to left half and even positioned to right half in-place

前端 未结 5 1662
别跟我提以往
别跟我提以往 2020-12-01 03:49

Given an array with positive and negative integers, move all the odd indexed elements to the left and even indexed elements to the right.

The difficult part of the p

5条回答
  •  感情败类
    2020-12-01 04:42

    I tried to implement as Evgeny Kluev said, and here is the result:

    #pragma once
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    template< typename Iterator >
    struct perfect_shuffle_permutation
    {
    
        static_assert(std::is_same< typename std::iterator_traits< Iterator >::iterator_category, std::random_access_iterator_tag >::value,
                      "!");
    
        using difference_type = typename std::iterator_traits< Iterator >::difference_type;
        using value_type = typename std::iterator_traits< Iterator >::value_type;
    
        perfect_shuffle_permutation()
        {
            for (difference_type power3_ = 1; power3_ < std::numeric_limits< difference_type >::max() / 3; power3_ *= 3) {
                powers3_.emplace_back(power3_ + 1);
            }
            powers3_.emplace_back(std::numeric_limits< difference_type >::max());
        }
    
        void
        forward(Iterator _begin, Iterator _end) const
        {
            return forward(_begin, std::distance(_begin, _end));
        }
    
        void
        backward(Iterator _begin, Iterator _end) const
        {
            return backward(_begin, std::distance(_begin, _end));
        }
    
        void
        forward(Iterator _begin, difference_type const _size) const
        {
            assert(0 < _size);
            assert(_size % 2 == 0);
            difference_type const left_size_ = *(std::upper_bound(powers3_.cbegin(), powers3_.cend(), _size) - 1);
            cycle_leader_forward(_begin, left_size_);
            difference_type const rest_ = _size - left_size_;
            if (rest_ != 0) {
                Iterator middle_ = _begin + left_size_;
                forward(middle_, rest_);
                std::rotate(_begin + left_size_ / 2, middle_, middle_ + rest_ / 2);
            }
        }
    
        void
        backward(Iterator _begin, difference_type const _size) const
        {
            assert(0 < _size);
            assert(_size % 2 == 0);
            difference_type const left_size_ = *(std::upper_bound(powers3_.cbegin(), powers3_.cend(), _size) - 1);
            std::rotate(_begin + left_size_ / 2, _begin + _size / 2, _begin + (_size + left_size_) / 2);
            cycle_leader_backward(_begin, left_size_);
            difference_type const rest_ = _size - left_size_;
            if (rest_ != 0) {
                Iterator middle_ = _begin + left_size_;
                backward(middle_, rest_);
            }
        }
    
    private :
    
        void
        cycle_leader_forward(Iterator _begin, difference_type const _size) const
        {
            for (difference_type leader_ = 1; leader_ != _size - 1; leader_ *= 3) {
                permutation_forward permutation_(leader_, _size);
                Iterator current_ = _begin + leader_;
                value_type first_ = std::move(*current_);
                while (++permutation_) {
                    assert(permutation_ < _size);
                    Iterator next_ = _begin + permutation_;
                    *current_ = std::move(*next_);
                    current_ = next_;
                }
                *current_ = std::move(first_);
            }
        }
    
        void
        cycle_leader_backward(Iterator _begin, difference_type const _size) const
        {
            for (difference_type leader_ = 1; leader_ != _size - 1; leader_ *= 3) {
                permutation_backward permutation_(leader_, _size);
                Iterator current_ = _begin + leader_;
                value_type first_ = std::move(*current_);
                while (++permutation_) {
                    assert(permutation_ < _size);
                    Iterator next_ = _begin + permutation_;
                    *current_ = std::move(*next_);
                    current_ = next_;
                }
                *current_ = std::move(first_);
            }
        }
    
        struct permutation_forward
        {
    
            permutation_forward(difference_type const _leader, difference_type const _size)
                : leader_(_leader)
                , current_(_leader)
                , half_size_(_size / 2)
            { ; }
    
            bool
            operator ++ ()
            {
                if (current_ < half_size_) {
                    current_ += current_;
                } else {
                    current_ = 1 + (current_ - half_size_) * 2;
                }
                return (current_ != leader_);
            }
    
            operator difference_type () const
            {
                return current_;
            }
    
        private :
    
            difference_type const leader_;
            difference_type current_;
            difference_type const half_size_;
    
        };
    
        struct permutation_backward
        {
    
            permutation_backward(difference_type const _leader, difference_type const _size)
                : leader_(_leader)
                , current_(_leader)
                , half_size_(_size / 2)
            { ; }
    
            bool
            operator ++ ()
            {
                if ((current_ % 2) == 0) {
                    current_ /= 2;
                } else {
                    current_ = (current_ - 1) / 2 + half_size_;
                }
                return (current_ != leader_);
            }
    
            operator difference_type () const
            {
                return current_;
            }
    
        private :
    
            difference_type const leader_;
            difference_type current_;
            difference_type const half_size_;
    
        };
    
        std::deque< difference_type > powers3_;
    
    };
    

提交回复
热议问题