用异或操作实现的交换函数用以实现数组逆置中需要注意的问题

用元素交换函数实现数组逆置很简单,如下面代码:(数组左右元素交换)

#include<iostream>
#include<stdlib.h>
using namespace std;

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

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int lenth = sizeof(a) / sizeof(a[0]);
	int head = 0;
	int tail = lenth - 1;

	while (head <= tail)
	{
		swap(a[head], a[tail]);
		head++;
		tail--;
	}
	for (int i = 0; i < lenth; ++i)
	{
		cout << a[i] << endl;
	}
	system("pause");
}

有人会说,用异或操作实现交换函数效率更高,于是写下如下代码:

<span style="font-family:KaiTi_GB2312;">#include<iostream>
#include<stdlib.h>
using namespace std;

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

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int lenth = sizeof(a) / sizeof(a[0]);
	int head = 0;
	int tail = lenth - 1;

	while (head <= tail)
	{
		swap(a[head], a[tail]);
		head++;
		tail--;
	}
	for (int i = 0; i < lenth; ++i)
	{
		cout << a[i] << endl;
	}
	system("pause");
}</span>

一运行,结果大跌眼镜:0哪来的????

异或操作实现交换的机制: a ^ a = 0即同一个元素相异或之后为0

a =  a ^ b;

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

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

经分析:原来如此,当head = tail = (lenth-1)/ 2时,二者指向同一个元素,即

a = b = 3(同一块内存)

a = a ^ b = 3 ^ 3 = 0(内存内容改变为0)---->>> a = b = 0;

b = a ^ b = 0 ^ 0 = 0

a = a ^ b = 0 ^ 0 = 0

所以执行之后变为了0

那么该怎样修改呢???

while (head < tail)//改变此处
	{
		swap(a[head], a[tail]);
		head++;
		tail--;
	}

以后注意,把条件写成 while(head < tail)即同一个元素无需交换,即加快了执行效率,又可以避免上述问题!!

与其相关的一道面试题点击打开链接

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 16:00:49

用异或操作实现的交换函数用以实现数组逆置中需要注意的问题的相关文章

用异或操作实现的交换函数用以实现数组逆置中须要注意的问题

用元素交换函数实现数组逆置非常easy,如以下代码:(数组左右元素交换) #include<iostream> #include<stdlib.h> using namespace std; void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } int main() { int a[5] = { 1, 2, 3, 4, 5 }; int lenth = sizeof(a) / sizeof(a[0]);

让c++ 函数返回一个数组

让c++ 函数返回一个数组 在c++中是不允许数组作为函数的返回值的 int [] someFunction( ); //ILLEGAL 要想实现函数返回一个数组,那返回对应数组里面类型的指针 you must return a pointer to the array base type and have the pointer point to the array. So, the function declaration would be as follows:  int* someFun

为什么三次异或操作可以交换两个数

a和b是两个整数,经过以下三次异或操作,可以达到交换目的:a = a ^ b;b = a ^ b;a = a ^ b; 首先要理解,什么是^(异或)操作: 二进制两数运算结果: 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0相同为0,不同为1 假设: a = 10 , 其二进制数为: 1010 b = 12 , 其二进制数为: 1100如果a和b交换,在二进制数看来,因为第一位和最后一位数相同,所以中间两位数只要交换一下就行了这个交换的过程,因为二制进中只有两个数

一个数据交换函数引发的思考

近日,在书中看到一个关于数据交换函数的源代码,发现挺有意思,具体代码如下: 1 void swap(int* a, int* b) 2 { 3 *a ^= *b ^= *a ^= *b; 4 } 根据 C 语言异或赋值操作符(^=)的计算规则和异或运算符(^)的运算法则,应按照从右到左的顺序进行计算,具体计算过程演示如下: 1 *a = *a ^ *b; 2 *b = *b ^ *a = *b ^ ( *a ^ *b ) = *a; //将式1代入 3 *a = *a ^ *b = ( *a ^

交换函数swap的三种实现方法

http://blog.csdn.net/GarfieldEr007/article/details/48314295 本文采用三种方式实现两个数之间的交换,分别是①借助辅助变量temp的swap函数,②采用加减法的swap函数 ,③使用异或运算的swap函数. 现在直奔主题: 1.借助辅助变量temp的swap函数 I.引用类型形参 [cpp] view plain copy void swap(int &a, int &b) //引用类型方式 { int temp; //辅助变量 te

C++ 中的异或操作^

好好的利用异或能够产生奇妙的效果. 异或运算的性质: 不论什么一个数字异或它自己都等于0.也就是说.假设我们从头到尾依次异或数组中的每个数字,那么终于的结果刚好是那个仅仅出现一次的数字.由于那些出现两次的数字所有在异或中抵消掉了. 例题: 给定大小是N的数组,数组里的元素互相不反复,元素的大小范围是1-(N+1).目标是找出第一个miss的数.要求时间复杂度O(N).空间是O(1). 由于这个数组总共仅仅有N 个元素,因此在1--N+1中必然有一个数不存在.设res =0, 使用异或操作,先让r

自定义交换函数

#include<stdio.h> #define N 20 void Swap(int *temp,int *cont) /*定义一个交换函数*/ { int var; var=*temp,*temp=*cont,*cont=var; return; } int main() { int a[N],i,j; for(i=0;i<N;i++) scanf("%d",&a[i]); for(i=1;i<N;i++){ for(j=0;j<N-i;j+

交换函数作业

#include<stdio.h>//定义头文件 int main()// 定义主函数 {int i,j;// 定义变量i,j int*p,*q; // 定义指针变量p,q void swap(int*a,int*b);// 声明交换函数 p=&i;// 将指针指向变量i q=&j;// 将指针指向变量j printf("请输入两个需要交换的数:\n");//打印"请输入两个需要交换的数"字样 scanf("%d,%d"

C++中交换函数的几种写法与辨析

#include <iostream> using namespace std; //错误方法, //这里是把主函数的a, b进行复制然后交换 //函数执行完毕后释放复制的a, b, //而没有保存a,b交换后的值 void fun_one(int x, int y) { int temp; temp = y; y = x; x = temp; } //正确的方法之一 //使用指针的交换 void fun_two(int *x, int *y) { int c = 0; c = *x; *x