您的位置:首页 > 编程语言 > Java开发

两种Java数字交换算法哪个快。

2015-12-11 14:54 295 查看

直接交换与临时空间交换算法比较

昨天在看到网上有问一段代码是什么作用,看了一下,是任意字符串逆序的功能。

大概是这样的。

char [] s =str.toString().toCharArray();
long  now =0;
int begin =0 ;int end=s.length -1;
while(begin<end){
s[begin]=(char) (s[begin]^s[end]);
s[end]=(char) (s[end]^s[begin]);
s[begin]= (char) (s[begin]^s[end]);
begin++;
end--;
}


以前还真没见过这么写的,第一直觉,这种交换不需要分配临时空间,我们知道新增内存是非耗时的操作。所以没有太细考虑就直接回复这个算法的性能应该不错,会比用临时交换空间的算法性能高很多。

结果今天一上线,就看到网友的拍砖。说是这个直接交换没有用经典的用临时空间交换算法快。

哦,然后呢,我就仔细想了下。

temp =a;
a= b;
b=temp;


真是,都是三次运算,而且用于交换的临时空间,也不用每次都审请,只用一个单元空间就够了。

但是临时空间交换真的会比直接交换快很多吗?

对于“超标量处理器”这个也没什么直观的认识,写个程序试试吧。

对150000000个随机字符串进行操作,结果被震撼了。

直接交换排序用了 278ms

而临时空间交换只用了154ms

相差了一近倍。

为什么会差这么多能,看到了直接交换的char。异或算是Int类型,而char是8位的所以,会不会是由它影响的呢?把直接交换的代码粗暴的改一下,看看结果再说。

while(begin<end){
int b,e;
b=s[begin];
e=s[end];
b=b^e;
e=b^e;
b=b^e;
s[begin]=(char)b;
s[end] =(char)e;
begin++;
end--;
}


结果,只用了150ms。不过这段代码只比原先少了一个强转,也不会快差这么多啊。再对比一下,数组取值的操作数量,是与交换排序算法的相同都是4个。数组的取值的时间复杂度好像是O(1),而直接赋值有说忽略不计的,有说O(1)的。算了,也搞不清楚,还是直接上代码吧。

数组读取

str = RandomString.getInstance().randomAlpha(9999);
char [] s =str.toString().toCharArray();
long now = System.currentTimeMillis();
for (int i = 0; i < 1200000000; i++) {
char a =s[999];
}
long  finish =  System.currentTimeMillis();
System.out.println(finish -now+"ms" );//花费701ms


直接赋值

str = RandomString.getInstance().randomAlpha(9999);
char [] s =str.toString().toCharArray();
long now = System.currentTimeMillis();
char b =s[999];
for (int i = 0; i < 1200000000; i++) {
char a =b;
}
long  finish =  System.currentTimeMillis();
System.out.println(finish -now+"ms" ); //花费425ms


差不多就到这吧,对于技术真不能想当然,离真相差的不止十万八千里。

虽然到最后也没有比较出到低哪个快,但java差不多就基本这个情况,不过有一点,以后再使用数组进行读取的话,看来最好先赋给一个变量再进一步操作。有时间再用C语言试试。

附,感谢caozhy网友的指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 算法