Perfect shuffle and mess, no auxiliary array

Before answering any specific question, please note that my goal is not to randomly move the array, but to perfect shuffle, like the one that the ideal dealer can do with a set of cards, that is, split the deck in half and perform one pass in randomly (alternating a card from one half of the deck with one card from the other half). (This is actually one exercise from algorithms in the third edition of C: Sedgewick: nbr 11.3 p. 445)

So, I'm not interested in algorithms like Fisher-Yates shuffle, etc.

Said that I want to avoid using any auxiliary array when performing shuffling, the code that I was able to deliver is as follows:

template<typename T>
void two_way_shuffle(vector<T>& data,int l,int r)
{
    int n=(r-l)+1;
    int m=(r+l)/2;
    if(n%2==0) ++m;
    int s,p{l+1};
    for(;p<=r;p+=2,m++)
    {
        s=data[m]; //Make space
        //Shift the elements
        for(int i{m};i>p;i--)
            data[i]=data[i-1];
        //Put the element in the final position
        data[p]=s;
    }
}


template<typename T>
void two_way_unshuffle(vector<T>& data,int l,int r)
{
    int n=(r-l)+1;
    if(n%2!=0){
        --r;
        --n;
    }
    int m=(r+l)/2;
    int s,p{l+1},w{r-1};
    for(;p<=w;p++,w--)
    {
        s=data[w];
        for(int i{w};i>p;i--)
            data[i]=data[i-1];
        data[p]=s;
    }
    //Complete the operation
    for(p=l+1,w=m;p<w;p++,w--)
        swap(data[p],data[w]);
}

, "p", , "w", , , "p", , [p] 's'. .. ( )

FROM: 12345678
TO:   15263748

FROM: IS THIS WORKING CORRECTLY OR NOT?
TO:   ICSO RTRHEICST LWYO ROKRI NNGO T?

FROM: SHUFFLING TEST
TO:   SNHGU FTFELSIT

unshuffle, , , clever . , , ( , ).

, .

, unshuffle? , ?

+4
1

, . , [lo, hi] , hi [lo, hi). :

0  1  2  3  4  5
   -------              swap [1, 3) and [3]
0  3  1  2  4  5
         ----           swap [3, 4) and [4]
0  3  1  4  2  5
               -        [5, 5) is empty: break

, , , , . : , hi lo, lo hi 2 1.

: lo hi . : lo hi, lo hi. , lo 1. ( 1, , 2.)

, lo hi, : unshufling, .

:

template<typename T>
void weave(std::vector<T>& data)
{
    size_t lo = 1;
    size_t hi = (data.size() + 1) / 2;

    while (lo < hi) {
        T m = data[hi];

        for (size_t i = hi; i-- > lo; ) data[i + 1] = data[i];

        data[lo] = m;
        lo += 2;
        hi++;
    }
}

template<typename T>
void unweave(std::vector<T>& data)
{
    size_t n = data.size();
    size_t lo = n + n % 2 - 1;
    size_t hi = lo;

    while (hi--, lo-- && lo--) {
        T m = data[lo];

        for (size_t i = lo; i < hi; i++) data[i] = data[i + 1];

        data[hi] = m;
    }    
}

, , , , . , lo hi.

0

Source: https://habr.com/ru/post/1589429/


All Articles