zoukankan      html  css  js  c++  java
  • 【编程题】不引入第三个变量,而交换两个变量的值

    不引入第三个变量,而交换两个变量的值

    方法一:算术运算

    1 int a,b;
    2 a=10;b=12;
    3 a=b-a;    //a=2;b=12
    4 b=b-a;    //a=2;b=10       
    5 a=a+b;    //a=12;b=10

    它的原理:把a,b看做数轴上的两个点。

    第一句“a=b-a”求出了ab两点之间的距离,并且将其保存在a中;

    第二句“b=b-a”求出了a到原点的距离(b到原点的距离减去ab两点距离),并且将其保存在b中;

    第三句“a=b+a”求出了b到原点的距离(a到原点的距离加上ab两点距离),并且将其保存在a中。

    缺点:只能用于数字类型,字符串的交换就不行。

    方法二:位运算

    1 int a=10,b=12;
    2 a=a^b;
    3 b=a^b;
    4 a=a^b;

    它的原理:任意一个数与任意一个给定的数异或两次,值不变。

    方法三:指针操作

     1 int *a,*b;
     2 a=new int(20);
     3 b=new int(10);
     4 if(a<b)
     5 {
     6     a=(int*)(b-a);
     7     b=(int*)(b-(int(a)&0x0000ffff));
     8     a=(int*)(b+(int(a)&0x0000ffff));
     9 }
    10 else
    11 {
    12     b=(int*)(a-b);
    13     a=(int*)(a-(int(b)&0x0000ffff));
    14     b=(int*)(a+(int(b)&0x0000ffff));
    15 }

    它的原理:它交换的是a和b的地址,而变量的值在内存中是没有移动过的。

    其中,与运算“int(a)&0x0000ffff”,因为地址中高16位为段地址,后16位为位移地址,将它和0x0000ffff进行与运算后,段地址被屏蔽,只保留位移地址。例如:若&a=0x008f0200h,&b=0x008f1200h,在执行“a=(int*)(b-a);”时,a的值并不是0x00000200h,而是要加上变量a所在内存区的基地址,即实际结果是0x008f0200h。其中,0x008f是基地址,0200是a在该内存区的位移。

    其次,地址运算不能出现负数,所以要先判断a和b的大小。

    如有不对的地方,非常欢迎给予指导!

    ——【感谢】资料来源于http://blog.csdn.net/kangkermit/article/details/21371159

  • 相关阅读:
    [JSOI2008]巨额奖金(最小生成树计数)
    [HAOI2008] 糖果传递
    [SCOI2009]生日快乐
    BZOJ2821 作诗
    [HAOI2008]圆上的整点
    POJ1741
    AC自动机
    [JSOI2008]星球大战starwar
    二分图有关证明(感性版)
    初识Pentaho(一)
  • 原文地址:https://www.cnblogs.com/engraver-lxw/p/7788564.html
Copyright © 2011-2022 走看看