• 交换两个整型数的方法


    交换两个整型数是C/C++中最常见的操作。

    实现这个操作的方法很多。

    最基本的方法就是使用一个临时变量,具体的代码如下:

    int a,b;
    int tmp;
    tmp=a;
    a=b;
    b=tmp;

     如果以函数的形式写出来的话就是:

    void swap(int *a,int *b)
    {
    int tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
    }

     在C++中,可以使用引用来实现的比较优雅:

    void swap(int& a,int &b)
    {
    int tmp;
    tmp=a;
    a=b;
    b=tmp;
    }

     另外,还经常出现的一种情况是不使用临时变量来交换两个整型数,一般常见的方法有两种:加法和异或运算,具体如下表所示:

    void swap1(int& x,int& y)
    {
    x=x+y;
    y=x-y;
    x=x-y;
    }
    void swap2(int &x,int &y)
    {
    x=x-y;
    y=x+y;
    x=y-x;
    }
    void swap3(int& x,int& y)
    {
    x ^= y;
    y ^= x;
    x ^= y;
    }

    x和y同号的情况下容易溢出

    x和y异号的情况下容易溢出

     

    左边的两种交换也存在问题就是整数的溢出。

    还有一种情况就是输入是swap(a,a)的情况。这样的话就会出问题。

    所以更严谨的做法如下:

    void swap4(int &x,int &y)
    {
    if(x==y)
    return ;
    if((x>0&&y>0)||(x<0&&y<0)) {
    x=x-y;
    y=x+y;
    x=y-x;
    }
    else{
    x=x+y;
    y=x-y;
    x=x-y;
    }
    }
    void swap5(int &x,int &y)
    {
    if(x==y)
    return;
    x^=y;
    y^=x;
    x^=y;
    }
    void swap7(int &x,int &y)
    {
    if(x==y)
    return;
    y=x+y-(x=y);
    }

     引申:

    在C++中支持模板操作,所以,可以利用这个写一个通用的swap操作:

    template <class T>
    void swap ( T& a, T& b )  
    {  
    T c(a); 
    a=b; 
    b=c;  

     这个其实是C++标准模板库中函数。该函数可以交换任意两个类型:

    // swap algorithm example
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    int main () {
      int x=10, y=20;                         // x:10 y:20
      swap(x,y);                              // x:20 y:10

      vector<int> first (4,x), second (6,y);  // first:4x20 second:6x10
      swap(first,second);                     // first:6x10 second:4x20

      cout << "first contains:";
      for (vector<int>::iterator it=first.begin(); it!=first.end(); ++it)
        cout << " " << *it;
    //first contains: 10 10 10 10 10 10
      cout << endl;
      return 0;
    }

     除此之外,在标准C++中string,vector,map,set等容器都是有swap函数的。

     下面是一些简单的例子:

    // swap strings
    #include <iostream>
    #include <string>
    using namespace std;
    main ()
    {
      string buyer ("money");
      string seller ("goods");

      cout << "Before swap, buyer has " << buyer;
      cout << " and seller has " << seller << endl;

      seller.swap (buyer);

      cout << " After swap, buyer has " << buyer;
      cout << " and seller has " << seller << endl;
    //Before swap, buyer has money and seller has goods
    //After swap, buyer has goods and seller has money
      return 0;
    }
    // swap vectors
    #include <iostream>
    #include <vector>
    using namespace std;

    int main ()
    {
      unsigned int i;
      vector<int> first (3,100);   // three ints with a value of 100
      vector<int> second (5,200);  // five ints with a value of 200

      first.swap(second);

      cout << "first contains:";
      for (i=0; i<first.size(); i++) cout << " " << first[i];

      cout << "\nsecond contains:";
      for (i=0; i<second.size(); i++) cout << " " << second[i];
    //first contains: 200 200 200 200 200 
    //second contains: 100 100 100 
      cout << endl;

      return 0;
    }
    // swap maps
    #include <iostream>
    #include <map>
    using namespace std;

    int main ()
    {
      map<char,int> foo;
      map<char,int> bar;
      map<char,int>::iterator it;

      foo['x']=100;
      foo['y']=200;

      bar['a']=11;
      bar['b']=22;
      bar['c']=33;

      foo.swap(bar);

      cout << "foo contains:\n";
      for ( it=foo.begin() ; it != foo.end(); it++ )
        cout << (*it).first << " => " << (*it).second << endl;

      cout << "bar contains:\n";
      for ( it=bar.begin() ; it != bar.end(); it++ )
        cout << (*it).first << " => " << (*it).second << endl;

      return 0;
    }
    foo contains:
    a => 11
    b => 22
    c => 33
    bar contains:
    x => 100
    y => 200
    // swap sets
    #include <iostream>
    #include <set>
    using namespace std;

    main ()
    {
      int myints[]={12,75,10,32,20,25};
      set<int> first (myints,myints+3);     // 10,12,75
      set<int> second (myints+3,myints+6);  // 20,25,32
      set<int>::iterator it;

      first.swap(second);

      cout << "first contains:";
      for (it=first.begin(); it!=first.end(); it++) cout << " " << *it;

      cout << "\nsecond contains:";
      for (it=second.begin(); it!=second.end(); it++) cout << " " << *it;

      cout << endl;

      return 0;
    }
    first contains: 20 25 32
    second contains: 10 12 75

    另外,还有不使用临时变量交换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;

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

    #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;
    }

    参考:http://blog.csdn.net/lpt19832003/article/details/5334688

  • 相关阅读:
    SVN简介
    TFS简介
    UML简介
    C#++c1FlexGrid+帮助文档09
    vmware虚拟机 C硬盘空间 无损扩容 新测
    批处理命令中set定义的两种变量介绍 计算机基础知识
    ASP.NET获取网站根目录(路径)
    VMware(bridge、NAT、host-only、custom)含义
    spring3.0+Atomikos 构建jta的分布式事务
    在做了 BasePage 时: 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 / / 节中包括
  • 原文地址:https://www.cnblogs.com/xkfz007/p/2505376.html
Copyright © 2020-2023  润新知