为什么以下“交换”操作会在随机时间失败?
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];
}
与this answer中的逻辑没有什么不同 它将适用于3/4运行,然后开始复制0
在C和C ++中尝试过相同的结果
[编辑]
通过初始化p=0
并使用while (p==i) p = rand() % 11;
更新: reason NOT to use xor
(请参阅Mark Byers' answer和评论)
答案 0 :(得分:6)
如果p
恰好与i
相同,则a[i] ^ a[p]
将为零,其余功能将失败。
从统计数据来看,您的代码实际上有65%的机会以这种方式失败。
确保在生成p
时,它与i
的数字不同。例如:
p = rand() % 10;
if( p >= i) p++;
答案 1 :(得分:5)
当i
等于p
时,a[i] ^ a[p]
变为零。你的“交换”操作被打破了。
要交换,您应该使用临时变量:
int temp = a[i];
a[i] = a[p];
a[p] = temp;
不要使用XOR黑客。
答案 2 :(得分:1)
因为p
随机等于i
。在这种情况下,a[i]
立即变为0。
答案 3 :(得分:1)
如果i == p
,则a[i]
会存储0
。
答案 4 :(得分:1)
作为开发实践,不建议进行XOR交换。但是如果你使用逻辑来获得乐趣,那么使用这一行将确保p与i不相同。
p = ((rand()%10)+(i+1))%11;
或
p = ((rand()%(count-1))+(i+1))%count;
但请注意,这个技巧对于性能视角并不好,因为它需要两个模块运算符和一个加法(或减法)。使用精确比较(这是最快的比较运算符),如果它们相同则加1。
p = rand()%10;
if (p == i) p++;