【数据结构与算法】原地交换两个整数值


原地交换两个整数值

一般的做法,我们要交换两个整数的值都要定义一个临时变量来存储,那有没有其他的方法可以交换变量的值呢?

// 使用临时变量交换两个整型的值
void swap(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp; 
}

我们知道,异或的运算规则可以简单的描述为: 相同为0,不同为1。

例如:10与14异或,得到4,记为:a与b异或得到c。
10  : 1010 -> a
14  : 1110 -> b
xor : 0100 -> c

稍微观察,我们可以发现,c再与a异或,会得到b,而c与b异或,会得到c:
a   : 1010
c   : 0100
xor : 1110 -> b
---------------
a   : 0100
b   : 1110
xor : 1010 -> a

我们可以利用这个特性,把待交换的两个值做异或处理,得到的异或结果我们可以存储在这两个变量中的任意一个(为方便描述,假设我们存储在a中,传入的变量a:b1010,b:b1110,此时a中是原来两个异或后的结果c:b0100)。
然后用另外一个(b:b1110)与之(a:b0100 也就是原来两个异或后的结果c)做异或运算得到原来被覆盖的那个变量(原来的a),存储在没有被覆盖的这个变量(b:b1010)中,此时这个变量已完成交换。
最后,用已完成交换的这个变量(b:b1010)再和原来被覆盖的那个变量(a:b0100)再做异或运算,结果存储在原来被覆盖的那个变量中(a:b1110),此时得到的值就是没有被覆盖的这个变量原来的值。
这样,我们就没有借助临时变量,成功的把两个变量的值进行了交换!


实验代码如下:

#include<iostream>
#include<malloc.h>

using namespace std;

void out_binary(int a)
{
	// 初始化字符串 
	int weight = sizeof(a) * 8;
	char *out_str = (char *) malloc(sizeof(char) * weight + 1);
	for(int i = 0; i<weight;i++)
	{
		out_str[i] = '0';
	}
	out_str[weight] = '/0';
	
	// 短除法,获取二进制字符串 
	int index = weight;
	while(a != 1)
	{
		int r = a % 2;	
		a /= 2;
		out_str[index] = r + '0';
		index--;
	}
	out_str[index] = a + '0';
	
	// 打印输出
	cout<< out_str ;
}

// 原地交换两个值,使用xor异或操作 
void swap(int *a, int *b)
{
	cout << "第一步:a与b异或得到加密后的a" << '/n'; 
	*a = *a ^ *b; // 核心1(可简写为:*a^=*b) 
	cout << "a : "<<*a <<"; b : "<< *b << '/n';
	cout << "a : ";
	out_binary(*a);
	cout << '/n';
	cout << "b : ";
	out_binary(*b);
	cout << '/n';
	
	cout << "第二步:b与加密后的a异或得到原来的a,此时赋值给b,b为原来的a" << '/n'; 
	*b = *b ^ *a; // 核心2(可简写为:*b^=*a) 
	cout << "a : "<<*a <<"; b : "<< *b << '/n';
	cout << "a : ";
	out_binary(*a);
	cout << '/n';
	cout << "b : ";
	out_binary(*b);
	cout << '/n';
	
	cout << "第三步:原来的a与加密后的a异或得到原来的b" << '/n';
	*a = *a ^ *b; // 核心3(可简写为:*a^=*b) 
	cout << "a : "<<*a <<"; b : "<< *b << '/n';
	cout << "a : ";
	out_binary(*a);
	cout << '/n';
	cout << "b : ";
	out_binary(*b);
	cout << '/n';
}



int main()
{
	cout<<"异或规则:相同为0,不同为1。"<<'/n';
	cout<<"利用的特点:a与b异或后得到的值与其中任意一个数异或得到另外一个值。"<<'/n';
	int a = 10, b = 14;
	swap(&a,&b);
	cout <<"结果:"<<"a->"<< a <<",b->"<< b << '/n';
	return 0;
}

其实就一点点代码:

// 原地交换两个值,使用xor异或操作 
void swap(int *a, int *b)
{
	*a^=*b;
	*b^=*a;
	*a^=*b;
}

原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/273368.html

(0)
上一篇 2022年7月10日
下一篇 2022年7月10日

相关推荐

发表回复

登录后才能评论