现在的位置: 首页 > 综合 > 正文

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

2013年06月20日 ⁄ 综合 ⁄ 共 2642字 ⁄ 字号 评论关闭

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


方法一: 

通过临时变量实现,也是最常见的方法:  
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个数据的数组排序得到的时间,只是在我的电脑上测试了可能不是很准确,但是应该可以供给大家做参考。很显然抑或交换是效率最差的。


抱歉!评论已关闭.