我从我的一个朋友那里听说,最好的交换算法是“(a^=b^=a^=b)”,其中 a 和 b 是要交换的两个整数。但是当我使用 c 语言应用它时,它导致崩溃。你们中的任何人都可以解释可能的原因吗?请建议最好的交换算法。谢谢你!!!!伙计们,我想知道崩溃的原因。
6 回答
这种交换技巧有时很危险,我看到一个错误的快速排序程序使用这种交换会产生错误的结果。但是通常的交换会生成正确的程序。
就速度而言,如果我们使用 tmp 变量,编译器有时会生成更快的代码。
采用tmp = a; a = b; b = tmp;
a^=b^=a^=b;
可能会崩溃,因为它调用了可怕的未定义行为。它打破的规则是它在a
没有中间序列点的情况下修改了两次。它可以通过插入一些序列点来修复 - 例如,使用逗号运算符:
a ^= (b ^= a ^= b, b);`
或者通过将其分解为多个语句:
b ^= a ^= b; a ^= b;
但是,它通常仍然是交换变量的不好方法——其他几个答案和评论已经充分解释了原因。
请参阅http://en.wikipedia.org/wiki/Swap_(computer_science)。
使用临时变量会产生更多开销,但比 XOR 交换算法更稳定,并且并行计算使其比 XOR 交换更快。
有关使用临时变量进行交换的可靠实现,请参见http://www.ibm.com/developerworks/linux/library/l-metaprog1.html的第一个代码示例。
编写人类阅读速度更快的代码。并且相信编译器在大多数情况下能够生成更好的代码。进行分析,看看这是否是提高速度的唯一地方。然后应用上面多次列出的 XOR 解决方案,它可能并不适用于所有地方。
好吧,在这种情况下,我们可以使用数学来交换没有第三个变量的两个数字
- 您需要学习一些规则,如下所示;
假设你有两个变量A = 10 和 B = 20 ,所以现在如果你把它们都加起来,你会得到30的总数。
现在,如果从总计中减去 A ,则结果为B,如果从总计中减去 B,则结果为A。
例如:
A = (A+B)-A; //(10 + 20) -10; ===> we will get 20 as a result
B = (A+B)-B; //(10 + 20) -20; ===> we will get 10 as a result
因此,通过这种技术,您了解通过从两个数字的总数中减去一个数字,我们将得到另一个数字。
所以现在交换两个数字的最终答案如下
A=(A+B)-(B=A)
所以这里我们从 A 和 B 的总和中减去 A,所以我们得到 A 中的 B 作为结果,我们通过赋值得到 B 中 A 的值;``
将此逻辑用于数值:
int a = 10, b =5 ;
a = a-b;
b = b+a ; // b gets the original value of a
a = b - a; // a gets the original value of b
printf ("value : %d %d \n",a ,b) ;