A shuffle function is defined as
Shuffle( A[n-1],A[n-2].....A[1],A[0]) = A[n-2]A[n-3]......A[1],A[0],A[n-1]
where i in A[i] represent the I th bit in开发者_如何学Python the binary representation of the index in the array . The
For example , the shuffle of the third element in an array is fifth array element. i.e..
Shuffle(A[010]) = A[100]. (Assuming the array size as 8 elements)
We see that the n-1 th bit '0' is left circular shifted . So the value of A[4] is copied into A[2]. Can we perform this without using a temporary array for all the elements in the array ...
I want to implement this function in simple plain C , but i just could not understand how to change the bits ...
Suggestions please...
Have you considered the Knuth Shuffle?
Here is an example in C from RosettaCode:
#include <stdlib.h>
#include <string.h>
int rrand(int m)
{
  return (int)((double)m * ( rand() / (RAND_MAX+1.0) ));
}
#define BYTE(X) ((unsigned char *)(X)) 
void shuffle(void *obj, size_t nmemb, size_t size)
{
  void *temp = malloc(size);
  size_t n = nmemb;
  while ( n > 1 ) {
    size_t k = rrand(n--);
    memcpy(temp, BYTE(obj) + n*size, size);
    memcpy(BYTE(obj) + n*size, BYTE(obj) + k*size, size);
    memcpy(BYTE(obj) + k*size, temp, size);
  }
  free(temp);
} 
You can change bits using the bitwise logical operators &, | etc.  You can move bits using the shift << and >> operators. 
It's easiest to do this using a temporary array, since otherwise how do you avoid overwriting a value you will need later?
I do not remember where I found this method (may be "Numerical recipes in C", but I cannot fint it there).
Method use bit reversed shuffle (i'll name it "bitrev" here), it reorders array elements that element index abcdef becomes fedcba (letters represent bits, 6 bit example). Three bit reverts do your functions:
Use two bitrevs to two halves of array, so index
abcdefbecomeafedcb(when you act on bitrev on half of array highest index bit remains the same);Use bitrev on whole array, so index
afedcbbecomebcdefa, and that's what you need.
As bitrev is easily implemented inplace this do your work.
// this function has complexity O(N)
void shuffle(char *p, unsigned int pSize)
{
        unsigned int i = 0;
        for(i=0 ; i < (pSize - 1); i++)
        {
        char lTmpChar=p[i];
        p[i]=p[i+1];
        p[i+1]=lTmpChar;
        }
}
or using templates (c++):
template <typename T> void shuffle(T *p, unsigned int pSize)
{
        unsigned int i = 0;
        for(i=0 ; i < (pSize - 1); i++)
        {
        T lTmpChar=p[i];
        p[i]=p[i+1];
        p[i+1]=lTmpChar;
        }
}
You may use the shuffle function with an index which is an array of char, for example:
int arraySize = 10;
char array[arraySize]='abcdefghil';
char index[4]='0010';
int shuffled_index = atoi(shuffle(index,4));
if(shuffled_index < arraySize) // note that shuffled_index is not always valid
{
printf("Char: %c", array[shuffled_index]);
}
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
 加载中,请稍侯......
      
精彩评论