[挑战]还有比我这个更短更好的swap方法吗

qq13833254607 2012-07-23 05:44:01

namespace test
{
using System;
class Program
{
static void Main(string[] args)
{
int a, b;
a = 100;
b = 3;
b = a + 0 * (a = b);
Console.WriteLine(a + "," + b);
}
}
}

今天突然想到的,在网上搜了半天没发现同样的,和其他的一些方法比了一下,我觉得我这个是最优的了,最起码从效率上毫无疑问是最优的,看IL就知道

//000011: b = a + 0 * (a = b);
IL_0005: ldloc.0
IL_0006: ldloc.1
IL_0007: stloc.0
IL_0008: stloc.1

没有运算,只有赋值

反汇编也差不多,

b = a + 0 * (a = b);
0000002f mov eax,dword ptr [ebp-8]
00000032 mov dword ptr [ebp-10h],eax
00000035 mov eax,dword ptr [ebp-0Ch]
00000038 mov dword ptr [ebp-8],eax
0000003b mov eax,dword ptr [ebp-10h]
0000003e mov dword ptr [ebp-0Ch],eax
...全文
1733 64 打赏 收藏 转发到动态 举报
写回复
用AI写文章
64 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjjwind 2012-08-22
  • 打赏
  • 举报
回复

mov eax,1
mov ebx,2
push eax
push ebx
pop eax
pop ebx

话说这个会更好
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 56 楼 的回复:]

gcc 下是不可以的。这样的代码是垃圾!
[/Quote]

为何是垃圾,有用就不是垃圾,C#里面,这个比+和^都快,很好用
coFinder 2012-08-15
  • 打赏
  • 举报
回复
算法:看看这个

a = a ^ b;

b = a ^ b;

a = a ^ b;
赵4老师 2012-08-14
  • 打赏
  • 举报
回复
#include <stdio.h>
#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)
char *p1="1" ,*p2="2" ;
char c1=1 , c2=2 ;
short s1=1 , s2=2 ;
int i1=1 , i2=2 ;
__int64 I1=1i64, I2=2i64;
float f1=1.0f, f2=2.0f;
double d1=1.0 , d2=2.0 ;
void main() {
SWAP((int)p1,(int)p2); printf("char * %5s, %5s\n",p1,p2);
SWAP(c1,c2); printf("char %5d, %5d\n",c1,c2);
SWAP(s1,s2); printf("short %5d, %5d\n",s1,s2);
SWAP(i1,i2); printf("int %5d, %5d\n",i1,i2);
SWAP(I1,I2); printf("__int64 %5I64d,%5I64d\n",I1,I2);
SWAP(*(int *)&f1,*(int *)&f2);printf("float %5g, %5g\n",f1,f2);
SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double %5lg, %5lg\n",d1,d2);

SWAP(c1,c1);
printf("%d\n",c1);
}
//char * 2, 1
//char 2, 1
//short 2, 1
//int 2, 1
//__int64 2, 1
//float 2, 1
//double 2, 1
//2
qq13833254607 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 60 楼 的回复:]

C/C++ code
#include <stdio.h>
#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)
char *p1="1" ,*p2="2" ;
char c1=1 , c2=2 ;
short s1=1 , s2=2 ;
in……
[/Quote]

看不懂那个do while是干嘛的

而且gcc上跑的结果有些不对
http://ideone.com/7WkOI

char * 2, 1
char 2, 1
short 2, 1
int 2, 1
__int64 2, 1
float 2, 2
double 2, 2
2
WithoutMe2012 2012-08-14
  • 打赏
  • 举报
回复
长见识了,要从编译器的角度来认识这个问题的深度
jzq526 2012-08-13
  • 打赏
  • 举报
回复
我试了,java下可以,我用的JDK 7.这种代码用来开阔思路还是很好的,我决定给我的学生讲讲,但是一定会说明这个算法对运算顺序的依赖是很大的。
jzq526 2012-08-13
  • 打赏
  • 举报
回复
短小精悍,不错。不过这取决于你的编译器如何来确定计算顺序了。
qq13833254607 2012-08-13
  • 打赏
  • 举报
回复
试了GCC下确实不行啊
http://ideone.com/gjAG3
BYD123 2012-08-13
  • 打赏
  • 举报
回复
gcc 下是不可以的。这样的代码是垃圾!
再见理想~ 2012-08-13
  • 打赏
  • 举报
回复
a=^b=^a=^b;
ayacbc1881 2012-08-11
  • 打赏
  • 举报
回复
楼主的代码不清晰,不知道效率如何
orzgods 2012-08-11
  • 打赏
  • 举报
回复
这个取决于编译器啊,编译器把你的这条语句解释成机器码,b = a + 0 * (a = b)
其中0*(a=b)这个中间变量肯定要被保存起来,然后再与a相加,最后赋值给b,
一共是1赋值,1乘法运算,1赋值,1加法运算,1赋值。
我对c#编译器不熟悉,但我感觉如果这个快的话,肯定是编译器的优化,不是算法的优化。。。
YFLK 2012-08-10
  • 打赏
  • 举报
回复
我是不会用LZ的方法!

[Quote=引用 14 楼 的回复:]

不用第三变量的,还有几种方法
a=a+b;
b=a-b;
a=a-b;



a^=b;
b^=a;
a^=b;
[/Quote]
但14楼第一种方法有溢出风险,也不能采用。
q156375764 2012-08-10
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分
  • 打赏
  • 举报
回复
这一步 b = a + 0 * (a = b);
中间那个乘法 *
不就是运算符号吗
* 的运算很复杂的
效率很低的
qq13833254607 2012-08-09
  • 打赏
  • 举报
回复
再提一句,看了下网站上面是居然是mono的结果,看来mono优化的也不错啊
qq13833254607 2012-08-09
  • 打赏
  • 举报
回复
http://ideone.com/GB2n3

在云计算里面提高的效果更高,居然提高了4倍

結果: success time: 0.1s 記憶體: 37048 kB 回傳值: 0

input: 無
output:
29
30
8
qq13833254607 2012-08-09
  • 打赏
  • 举报
回复
我觉得这作为优化技巧来说还是有一定意义的,毕竟可以生成最优代码,不要小看这点的提高,要是把这个用在排序算法里边那就相当于提高了30%的交换速度
iCan.club 2012-08-09
  • 打赏
  • 举报
回复
说明编译器优化好
跟算法有毛的关系
push a
push b
pop a
pop b
加载更多回复(42)

7,765

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧