随机播放功能定义为
Shuffle( A[n-1],A[n-2].....A[1],A[0]) = A[n-2]A[n-3]......A[1],A[0],A[n-1]
其中A [i]中的i表示数组中索引的二进制表示中的第I位。
例如,数组中第三个元素的shuffle是第五个数组元素。即..
随机(A [010])= A [100]。 (假设数组大小为8个元素)
我们看到第n-1位'0'被左旋转。因此A [4]的值被复制到A [2]中。我们可以在不使用数组中所有元素的临时数组的情况下执行此操作...
我想在简单的普通C中实现这个功能,但我只是无法理解如何更改位...
建议请...
答案 0 :(得分:1)
您是否考虑过Knuth Shuffle?
以下是来自RosettaCode的C中的示例:
#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);
}
答案 1 :(得分:0)
您可以使用按位逻辑运算符&
,|
等来更改位。您可以使用shift <<
和>>
运算符移动位。
使用临时数组执行此操作最简单,否则如何避免覆盖以后需要的值?
答案 2 :(得分:0)
我不记得我在哪里找到了这种方法(可能是“C中的数字食谱”,但我不能在那里伪装)。
方法使用bit reversed shuffle(我在这里将它命名为“bitrev”),它重新排序元素索引abcdef
变为fedcba
的数组元素(字母代表位,6位示例)。三位恢复可以完成您的功能:
使用两个bitrev到两半数组,因此索引abcdef
变为afedcb
(当你对数组最高索引位的一半上的bitrev进行操作时保持不变);
在整个数组上使用bitrev,因此索引afedcb
变为bcdefa
,这就是您所需要的。
由于bitrev很容易在现场实施,所以你的工作。
答案 3 :(得分:-1)
//此函数具有复杂度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;
}
}
或使用模板(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;
}
}
您可以使用带有索引的shuffle函数,该索引是char数组,例如:
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]);
}