交换两个整型数各种方法总结
来源:互联网 发布:传奇怪物算法 编辑:程序博客网 时间:2024/05/16 16:16
原文地址
交换两个整型数是C/C++中最常见的操作。
实现这个操作的方法很多。
最基本的方法就是使用一个临时变量,具体的代码如下:
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;}
另外,还经常出现的一种情况是不使用临时变量来交换两个整型数,一般常见的方法有两种:加法和异或运算,具体如下表所示:
x和y同号的情况下容易溢出
x和y异号的情况下容易溢出
左边的两种交换也存在问题就是整数的溢出。
还有一种情况就是输入是swap(a,a)的情况。这样的话就会出问题。
所以更严谨的做法如下:
引申:
在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函数的。
下面是一些简单的例子:
#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;
}
#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
#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个整型数的操作,
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+
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;
好了,最后一个语句就实现了顺次交换五个变量的值,写程序验证如下:
#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;
}
- 交换两个整型数各种方法总结
- 交换两个整型数的一些方法总结
- 交换两个整型数的方法
- 交换两个数方法总结
- 交换两个数的方法总结
- Java中交换两个数的各种方法
- C++交换两个数总结
- 交换两个数的方法
- 不引入第三个变量交换两个整型数
- 比较两个数的大小,交换两个数的 方法总结
- C/C++中交换两个整型数值的方法
- 交换两个整型变量的四种方法
- 两种交换两个数方法
- 交换两个数的三种方法
- 两个数交换的三种方法
- 用指针的方法交换两个数
- 交换两个数的三种方法
- 交换两个数的五种方法
- 《Python核心编程》第二版第四章练习
- 顶点(vertexs) 图元(primitives) 片元(fragments片断) 像素(pixels)
- [leetcode] work break II
- 单片机按键消抖程序
- 一,申请验证开发者
- 交换两个整型数各种方法总结
- eclipse个人最近整理一些快捷键
- 简评游戏人工智能相关的中文书
- 二、配置微信公众平台回复接口
- Android TextView排版
- Chromium 嵌入式框架
- BZOJ 1502 NOI 2005 月下柠檬树 计算几何 自适应辛普森积分
- 判断一棵树是否是完全二叉树
- Uploadify buttonClass