交换变量值的方法,异或并不高效或者说是一个花哨的招聘产物

来源:互联网 发布:linux tar解压命令 编辑:程序博客网 时间:2024/06/08 10:47

    今天上午听同学说不用中间变量怎么交换两个变量的值,下面就罗列了几种交换值的方法,并且测试了交换变量值方法的效率。


方法一: 

通过临时变量实现,也是最常见的方法:  
void swap(int a ,int b) 
{
   int t;
   t=a;
   a=b; 
   b=t;
}   
t作为临时变量进行交换。这种算法易于理解
,效率也很高



方法二: 

算术运算,就是通过普通的+和-运算来实现:   
void swap(int a ,int b) 
{
   a=b-a; //a=20;b=30
   b=b-a; //a=20;b=10
   a=b+a; //a=30;b=10 
}
证 明:把a、b看做数轴上的点,围绕两点间的距离来进行计算。第一句“a=b-a”求出ab两点的距离,并且将其保存在a中;第二句“b=b-a”求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中;第三句“a=b+a”求出b到原点的距离(a到原点距离与ab两点距离之和),并 且将其保存在a中。完成交换。 此算法与方法一相比,多了三个计算的过程,没有借助临时变量。
当然你也可以写成这样: 
void swap(int a ,int b) 
{
   a=b+a;
   b=b-a;
   a=b-a;
}

当然也可以这样:

void swap(int a ,int b) { 
   a=b-a; 
   b=b-a;
   a=b+a;
}

同上面一个意思。
缺点:很可能造成溢出,需要加以判断。


方法三: 

原理为算术运算符的结合顺序为自左至右:  
void swap(int a ,int b) 
{
   a=b+(b=a)*0;
}

我学习c#不久暂时无法解释,请读者自行参考其他高手的博客。


方法四:

通过异或运算实现变量的交换
void swap(int a ,int b) 

    a=a^b;
    b=a^b;
    a=a^b;
}
很多人认为最为神奇,其实不然,我测试了一下,它的效率是这几个中效率最低的。老师讲这是哪个公司的面试题,但是你会发现花哨 != 高端,我想没有人会把它放进项目中。


下面是我用自己的电脑做了一个测试:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace C排序{    class Program    {
        /// <summary>        /// 算数交换        /// </summary>        /// <param name="a"></param>       #region       static void mathcmp(ref int[] a)       {           for (int i = 0; i < a.Length - 1; i++)           {               for (int j = 0; j < a.Length - 1 - i; j++)               {                   if (a[j] > a[j + 1])                   {                       a[j] = a[j + 1] + a[j] ;                       a[j+1] = a[j] - a[j + 1];                       a[j] = a[j] - a[j + 1];                   }               }           }       }       #endregion
        /// <summary>        /// 算数交换        /// </summary>        /// <param name="a"></param>       #region       static void mathcmp(ref int[] a)       {           for (int i = 0; i < a.Length - 1; i++)           {               for (int j = 0; j < a.Length - 1 - i; j++)               {                   if (a[j] > a[j + 1])                   {                       a[j] = a[j + 1] + a[j] ;                       a[j+1] = a[j] - a[j + 1];                       a[j] = a[j] - a[j + 1];                   }               }           }       }       #endregion
       /// <summary>       /// 语言特性交换两个数的值       /// </summary>       /// <param name="a">传入数组的名称</param>       #region       static void effcmp(ref int[] a)       {           for (int i = 0; i < a.Length - 1; i++)           {               for (int j = 0; j < a.Length - 1 - i; j++)               {                   if (a[j] > a[j + 1])                   {                       a[j] = a[j + 1] + (a[j + 1] = a[j]) * 0;                   }               }           }       }       #endregion
       /// <summary>       /// 冒泡抑或排序       /// 从小到大排序       /// </summary>       /// <param name="a">传入数组的名称</param>       #region       static void yihuomp(ref int[] a)       {           for (int i = 0; i < a.Length - 1; i++)           {               for (int j = 0; j < a.Length - 1 - i; j++)               {                   if (a[j] > a[j + 1])                   {                       a[j] = a[j] ^ a[j + 1];      //抑或交换两个数的值                       a[j + 1] = a[j] ^ a[j + 1];                       a[j] = a[j] ^ a[j + 1];                   }               }           }       }       #endregion       static void fuzhi(ref int[] a)       {           for (int i = 0; i < a.Length; i++)           {               a[i] = a.Length-i;           }       }

        static void Main(string[] args)        {            int[] arry = new int[80000];            fuzhi(ref arry);            DateTime d1 = DateTime.Now;            mp(ref arry);            DateTime d2 = DateTime.Now;            Console.WriteLine("冒泡“方法一中间变量”排序结束        用时:{0}\n", d2-d1);            fuzhi(ref arry);            DateTime d7 = DateTime.Now;            effcmp(ref arry);            DateTime d8 = DateTime.Now;            Console.WriteLine("冒泡“方法二算数”排序结束            用时:{0}\n", d8 - d7);            fuzhi(ref arry);            DateTime d5 = DateTime.Now;            effcmp(ref arry);            DateTime d6 = DateTime.Now;            Console.WriteLine("冒泡“方法三语言特性”排序结束          用时:{0}\n", d6 - d5);            fuzhi(ref arry);            DateTime d3 = DateTime.Now;            yihuomp(ref arry);            DateTime d4 = DateTime.Now;            Console.WriteLine("冒泡“方法四抑或”排序结束            用时:{0}", d4 - d3);            Console.ReadKey();        }
    }}
下图是用一个有80000个数据的数组排序得到的时间,只是在我的电脑上测试了可能不是很准确,但是应该可以供给大家做参考。很显然抑或交换是效率最差的。


原创粉丝点击