精华内容
下载资源
问答
  • 不用临时变量交换a,b值的三种方法.pdf
  • 不用临时变量交换两个变量的值 在学习C语言的时候,涉及到两个变量值的交换,其中用到临时变量。 类似于: 1 2 3 4 5 temp=a;   a=b;   b=temp; ...

    不用临时变量交换两个变量的值

    在学习C语言的时候,涉及到两个变量值的交换,其中用到临时变量。

    类似于:

    1
    2
    3
    4
    5
    temp=a;
     
    a=b;
     
    b=temp;

     这样的语句,如果在没有临时变量的情况下,该如何做呢?

    网络上的人们给出了两种方法:

    一、异或法

    1
    2
    3
    4
    5
    a=a^b;
     
    b=b^a;
     
    a=a^b;

     二、加减法

    1
    2
    3
    4
    5
    a = a + b; 
     
    b = a - b; 
     
    a = a - b;

     其实我们看加减法更容易理解,也有许多人用这种方法,虽然这些方法可能用不到,但是了解下还是有必要的,至少要读懂别人的代码是吧。

     

    下面是一些个人的分析:

    首先从简单的加减法来进行学习测试。

    a=a+b;

    此时a为两个数之和,我们用sum来表示,这样就变成了

    sum=a+b;

    b=a-b;

    这个步骤的时候,相当于

    b=sum-b;

    b=a+b-b=a;

    最后一步:a=a-b;

    也就是a=sum-b,这个时候,b已经变成了a,也就是

    a=sum-a=a+b-a=b;

    证明结束,嘿嘿,简单有趣吧。马上关灯了,明天测试另一个。

     

    今天来看看关于异或的情况

    首先是a=a^b;

    同理,我们设sum=a^b;

    第二步b=b^a; 相当于b=b^sum=b^a^b=a;

    第三步:a=a^b=sum^b=a^b^a=b;

     

    其实两个方法都类似,我们没有临时变量,就自己用一个来做临时变量(相当于临时变量)来完成我们的交换。

    当然,我们要注意,是不是所有的数据类型都能这样用呢?你可以自己试试哦!

    展开全文
  • 不用临时变量交换两个变量的值假定a = 1, b = 2; 不用临时变量交换a与b的值方法一: a = a + b; b = a - b; a = a - b; 第二句 b = a - b,其中 a = a + b,所以有 b = (a + b) - b = a; 第三句 a = a - b,...

    不用临时变量交换两个变量的值

    假定a = 1, b = 2; 不用临时变量交换a与b的值

    方法一:
    a = a + b;
    b = a - b;
    a = a - b;
    第二句 b = a - b,其中 a = a + b,所以有 b = (a + b) - b = a;
    第三句 a = a - b,其中 a = a + b,b = (a + b) - b,所以有 a = a + b - [(a + b) - b] = b;

    方法二:
    a = a ^ b;
    b = b ^ a;
    a = a ^ b;
    第二句 b = b ^ a,其中 a = a ^ b,所以有 b = b ^ (a ^ b) = a ^ 0 = a; 因为 b ^ b = 0;
    第三句 a = a ^ b,其中 a = a ^ b,b = b ^ (a ^ b),所以有 a = a ^ b ^ b ^ (a ^ b) = b;

    展开全文
  • 不用临时变量交换变量ab , 是一道很常见的题,下面是用一句话完成地 ,个人认为是最好的两种思路(1)是我的美女同事想出来的,膜拜,新颖而且精妙int a=10; int b=5; a=a+b-(b=a); System.out.println("a="+a+"b=...

    不用临时变量交换变量ab , 是一道很常见的题,

    下面是用一句话完成地 ,个人认为是最好的两种思路


    (1)是我的美女同事想出来的,膜拜,新颖而且精妙




    int a=10;
    int b=5;
    a=a+b-(b=a);		
    System.out.println("a="+a+"b="+b);

    (2)异或运算

    int a1=100;
    int b1=99;
    a1=(a1^=b1)^(b1^=a1);
    System.out.println("a1="+a1+"b1="+b1);



    补充知识:


    参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。即:0^0=0, 1^0=1, 0^1=1, 1^1=0

    例如:10100001^00010001=10110000

    0^0=0,0^1=1 0异或任何数=任何数

    1^0=1,1^1=0 1异或任何数-任何数取反

    任何数异或自己=把自己置0

    (1)按位异或可以用来使某些特定的位翻转,如对数10100001的第2位和第3位翻转,可以将数与00000110进行按位异或运算。

              10100001^00000110=10100111 //1010 0001 ^ 0x06 = 1010 0001 ^ 6

    (2)通过按位异或运算,可以实现两个值的交换,而不必使用临时变量。例如交换两个整数a,b的值,可通过下列语句实现:

        a=10100001,b=00000110

        a=a^b;   //a=10100111

        b=b^a;   //b=10100001

        a=a^b;   //a=00000110

    (3)异或运算符的特点是:数a两次异或同一个数b(a=a^b^b)仍然为原值a.






    展开全文
  • 不用临时变量交换两个数的值     当要交换两个数的值时,通常的做法是定义一个临时变量,然后再进行交换。那么能不能不用临时变量而交换两个数的值呢?可以的!C语言提供的异或运算就...

    不用临时变量交换两个数的值
     
     
    当要交换两个数的值时,通常的做法是定义一个临时变量,然后再进行交换。那么能不能不用临时变量而交换两个数的值呢?可以的!C语言提供的异或运算就可以实现这样的操作。
     
    异或运算符^也称XOR运算符,它的规则是若参加运算的两个二进位同号,则结果为0(假);异号为1(真)。即0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0。
     
    例:

    #include <stdio.h>

    int main(int argc, char *argv[])
    {
        int a = 2, b = 6;

        a = a ^ b;
        b = b ^ a;
        a = a ^ b;

        printf("a = %d b = %d/n", a, b);

        return 0;
    }

    结果如下:

    a = 6 b = 2

    分析:

    前两个赋值语句:“a = a ^ b;”和“b = b ^ a;”相当于b = b ^ (a ^ b),而b ^ a ^ b等于a ^ b ^ b。b ^ b的结果为0,因为同一个数与相向相^,结果必为0。因此b的值等于a ^ 0,即a,其值为2。

    再执行第三个赋值语句:“a = a ^ b”。由于a的值等于(a ^ b),b的值等于(b ^ a ^ b),因此,相当于a = a ^ b ^ b ^ a ^ b,即a的值等于a ^ a ^ b ^ b ^ b,等于b。

    2007.06.02
     
    今天又发现另外两种方法,特补上。
     
    方法一

    void swap(int *p, int *q)
    {
        *= *+ *q;
        *= *- *q;
        *= *- *q;
    }

    方法二

    void swap(int *p, int *q)
    {
        *= *+ *- (*= *p);
    }

    原理为算术运算符的结合顺序为自左至右。

    2007.06.18
     
    可以把异或的三条语句压缩为一条:
     

    a ^= b ^= a ^= b;

    要交换三个变量的值,可以用以下语句:

    = a + c - (= b, b = c);

    2007.09.11

    谢谢网友cool8jay指出上面红色部分的错误,下面来分析一下,先看一个示例程序,如下:

    #include <stdio.h>

    int main(int argc, char *argv[])
    {
        int a = 1;
        int b = 2;
        int c = 3;

        c = a + c - (= b, b = c);

        printf("a = %d/n", a);
        printf("b = %d/n", b);
        printf("c = %d/n", c);

        return 0;
    }

    编译运行,结果如下:

    a = 2 b = 3 c = 2

    可见,最初目标中的c = 1部分没能实现。于是分析原因:

    《The C Programming Language·Second Edition》P205介绍说,“The additive operators + and - group left-to-right”,即附加运算符加号和减号的结合顺序是自左向右;P209介绍说,“A pair of expressions separated by a comma is evaluated left-to-right, and the value of the left expression is discarded. The type and value of the result are the type and value of the right operand”,即逗号表达式的计算顺序是从左向右,逗号左边表达式的值被舍弃,表达式结果的类型和数值是逗号右边表达式的类型和数值。

    既然如此,那结果应该是正确的,为什么还会出错呢?再来看一下VC6.0下编译产生的汇编代码:

    7: int a = 1;
    00401028 mov dword ptr [ebp-4],1
    8: int b = 2;
    0040102F mov dword ptr [ebp-8],2
    9: int c = 3;
    00401036 mov dword ptr [ebp-0Ch],3
    10:
    11: c = a + c - (= b, b = c);
    0040103D mov eax,dword ptr [ebp-8]
    00401040 mov dword ptr [ebp-4],eax
    00401043 mov ecx,dword ptr [ebp-4]
    00401046 add ecx,dword ptr [ebp-0Ch]
    00401049 mov edx,dword ptr [ebp-0Ch]
    0040104C mov dword ptr [ebp-8],edx
    0040104F sub ecx,dword ptr [ebp-8]
    00401052 mov dword ptr [ebp-0Ch],ecx

    可以看到,第11行代码的执行过程如下:

    先把b的值赋给a,再把a和c的值相加,结果放在寄存器ecx中,然后把c的值赋给b,最后再把ecx与b的值相减,结果赋给c。分解为C语句为:

    = b; /* a = 2, b = 2 */
    ecx = a + c; /* ecx = 5, a = 2, c = 3 */
    = c; /* b = 3, c = 3 */
    = ecx - b; /* c = 2, ecx = 5, b = 3 */

    这下就清楚了,原来程序运行时先把逗号左边表达式的值计算出来丢弃掉,然后再做其它的运算,最开始的错误也就错在了这里。

    好了,既然上面的式子有问题,那有没有其它正确的方法能一条语句实现三个变量的值的交换呢?

     

    不用临时变量顺次交换N个变量的值
     
     
    有N(N>=2)个变量,不使用临时变量,如何顺次交换它们的值?能否只用一条语句实现?如
     
    +---+---+---+---+---+
    | a | b | c | d | e |
    +---+---+---+---+---+
    | 1 | 2 | 3 | 4 | 5 |
    +---+---+---+---+---+
     
    要把它变为
     
    +---+---+---+---+---+
    | a | b | c | d | e |
    +---+---+---+---+---+
    | 2 | 3 | 4 | 5 | 1 |
    +---+---+---+---+---+
     
    怎样实现?
     
    首先,我们考虑用异或实现两个变量的交换,可参考我的这篇文章《 不用临时变量交换两个数的值》。用C++写函数如下:
     

    int &swap(int &a, int &b)
    {
        b = b ^ a;
        a = a ^ b;
        b = b ^ a;

        return b;
    }

    然后可以把代码优化为:

    int &swap(int &a, int &b)
    {
        b ^= a;
        a ^= b;
        b ^= a;

        return b;
    }

    继续优化,把三句压缩为一句,如下:

    int &swap(int &a, int &b)
    {
        b ^= a ^= b ^= a;
        
        return b;
    }

    还可再优化,如下:

    int &swap(int &a, int &b)
    {
        return (b ^= a ^= b ^= a);
    }

    现在来顺次交换5个变量的值,如下:

    swap(a, b);        //返回b

    swap(b, c);        //返回c

    swap(c, d);        //返回d

    swap(d, e);        

    既然有返回值,那么可以写成链式的,如下:

    swap(a, b);                                 //返回b

    swap(swap(a, b), c);                        //返回c

    swap(swap(swap(a, b), c), d);               //返回d

    swap(swap(swap(swap(a, b), c), d), e);        

    现在,让我们来把swap函数依次用相应的函数体替换掉,如下:

    e ^= d ^= e ^= swap(swap(swap(a, b), c), d);

    e ^= d ^= e ^= d ^= c ^= d ^= swap(swap(a, b), c);

    e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= swap(a, b);

    e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

    好了,最后一个语句就实现了顺次交换五个变量的值,写程序验证如下:

    /******************************************************************
    * Copyright (c) 2005-2007 CUG-CS
    * All rights reserved
    *
    * 文件名称:xor.c
    * 简要描述:实现五个变量的顺次交换
    *
    * 当前版本:1.0
    * 作 者:raincatss
    * 完成日期:2007-10-18
    * 开发环境:Windows XP Sp2 + VC6.0
    * 个人博客:http://raincatss.cublog.cn/
    ******************************************************************/


    #include <stdio.h>

    #define PRINT(A) do {/
        printf("%d/n", A);/
        } while (0)

    int main()
    {
        int a = 1;
        int b = 2;
        int c = 3;
        int d = 4;
        int e = 5;

    //    b ^= a ^= b ^= a;        // swap(a, b)

    //    c ^= b ^= c ^= b;        // swap(b, c)

    //    d ^= c ^= d ^= c;        // swap(c, d)

    //    e ^= d ^= e ^= d;        // swap(d, e)


        e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

        PRINT(a);
        PRINT(b);
        PRINT(c);
        PRINT(d);
        PRINT(e);

        return 0;
    }

    运行结果如下:

    2 3 4 5 1

    测试结果正确,达到预定目标。

    知道了五个变量的顺次交换,那么任意多个变量的顺次交换就可以依次推导出来,在此我就不多写了。

    当然,除了本文介绍的方法外,还有其它方法可以实现不用临时变量交换任意多个变量的值,读者可以自己探索一下。


      转自 http://blog.csdn.net/lpt19832003/article/details/5334688

    展开全文
  • 不用临时变量交换a,b值的三种方法

    千次阅读 2019-03-30 19:27:50
    交换a,b的值是很基本的程序算法,但是绝大多数程序员加入了第三个参数完成二者的交换,那么有没有什么办法不用第三个参数实现交换的呢???来看以下的三种算法
  • 本文给出不使用中间变量交换两个变量值得源码方法。
  • 方法一:异或 void swap(int *a, int *b) { *a ^= *b; *b ^= *a; *a ^= *b; } 方法二:加减法 ...总结:经过反汇编验证,使用临时变量是效率最高的,其他的方法从可读性和执行效率来说都要差很多
  • 不用临时变量交换两个数

    千次阅读 2010-06-03 22:12:00
    今天在看王老师的Java项目题时,发现有个答案在进行二分法排序的时候,在交换变量这块,并没声明申请中间变量,而是直接进行异或交换,由于第一次遇到这样的情况,感觉非常新鲜,好奇之下探究了下,首先看看它的具体...
  • 首先看这样一个程序 int a, b; a = a + b; b = a - b; 此时b = (a + b) - b = a; (经过第一步a为a+b) ...可见这个程序实现了a和b的交换。注意+和-互为逆运算,可以得到(a+b)-b=a,埋个伏笔先。 在看这个例子: i
  • 那么能不能不用临时变量交换两个数的值呢?可以的!C语言提供的异或运算就可以实现这样的操作。 异或运算符^也称XOR运算符,它的规则是若参加运算的两个二进位同号,则结果为0(假);异号为1(真)。即0 ^ 0 = 0...
  • #include int main() { float a = 3.14f; float b = -5.23f; *(int*)(&a) ^= *(int*)(&b);...单精度浮点数在内存里占4个字节,里面的内容我们将其当做整数来处理,就可以使用异或运算,避免使用临时变量
  • /*不用临时变量交换两个变量的值,*/ //方法1 template void swap1(T& a, T& b) { a ^= b; b ^= a; a ^= b; } //方法2 template void swap2(T& a, T& b) { a = a + b; b = a - b; a = a - b; ...
  • int a,b; a=a^b; b=a^b a=a^b 最好的方法 a=a+b;...^是异或符号,异或这种运算有一个特点,那就是一个数被同一个数异或两次还是他本身: x=x^y^y,同时异或符合交换率:x=y^x^y
  • 那么能不能不用临时变量交换两个数的值呢?可以的!C语言提供的异或运算就可以实现这样的操作。 异或运算符^也称XOR运算符,它的规则是若参加运算的两个二进位同号,则结果为0(假);异号为1(真)。即0 ^ 0 =...
  • 题目:编写一个函数,不用临时变量,直接交换liangge

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 76,673
精华内容 30,669
关键字:

不用临时变量交换