0

Why would the following "swap" action fail at random times?

int i,p,a[11] = {0,1,2,3,4,5,6,7,8,9,10 };

srand(time(0));

for (i=0;i<11;i++)
{
    p = rand() % 11;
    a[i] = a[i] ^ a[p];
    a[p] = a[i] ^ a[p];
    a[i] = a[i] ^ a[p];
}

It is not so different from the the logic in this answer
It will work for a 3/4 runs and then start to duplicate 0

Tried it in C and C++, same results

[edit]
Solved by initializing p=0 and replacing the relevant line with while (p==i) p = rand() % 11;

Update: The reason NOT to use xor (see Mark Byers' answer and comment)

4

5 回答 5

6

如果p恰好与 相同ia[i] ^ a[p]则将为零,并且该函数的其余部分将失败。

从统计上看,您的代码实际上有 65% 的机会以这种方式失败。

确保在生成 时p,它与 不同i。例如:

p = rand() % 10;
if( p >= i) p++;
于 2012-07-03T19:26:58.023 回答
5

i等于pa[i] ^ a[p] 变为零。您的“交换”操作已损坏。

要交换,您应该使用临时变量:

int temp = a[i];
a[i] = a[p];
a[p] = temp;

不要使用 XOR hack。

于 2012-07-03T19:26:48.127 回答
1

作为一种开发实践,不建议进行异或交换。但是,如果您使用逻辑来取乐,那么请使用这条线,这将确保 p 与 i 不同。

p = ((rand()%10)+(i+1))%11;

或者

p = ((rand()%(count-1))+(i+1))%count;

但是请注意,这个技巧对于性能来说并不好,因为它需要两个模块运算符和一个加法(或减法)。使用精确比较(这是最快的比较运算符),如果相同则加 1。

p = rand()%10;
if (p == i) p++;
于 2012-07-03T20:43:54.943 回答
1

因为p随机等于i。在这种情况下,a[i]立即变为 0。

于 2012-07-03T19:27:00.280 回答
1

如果i == pthena[i]将存储0.

于 2012-07-03T19:27:49.843 回答