几个关于位运算的练习(局部到整体的思想)
1、
编写函数:
unsigned int reverse_bit(unsigned int value);
这个函数的返回值value的二进制位模式从左到右翻转后的值。
如:
在32位机器上25这个值包含下列各位:
00000000000000000000000000011001
翻转后:(2550136832)
10011000000000000000000000000000
程序结果返回:
2550136832
2、不使用(a+b)/2这种方式,求两个数的平均值。
3、编程实现:
一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。
请找出这个数字。(使用位运算)
4、
有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
要求:
不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)。
#include<stdio.h> #include<assert.h> #include<Windows.h> #pragma warning(disable:4996) //宏函数求平均值:浮点型!!! #define AVERAGE(x,y) (y-x)/2.0+x //有+就可能有溢出问题 //位运算//整数平均 #define AVERAGE2(x,y) (x&y)+((x^y)>>1) //思路: //从最低位获取每一个比特位; //利用局部变量r来表示数的每一位 //通过循环左移r并或上步获取的比特位 //所以,value的最低位就是r的最高位 //达到翻转的效果 unsigned int reverse_bit(unsigned int value) { int r = 0; for (int i = 0; i < 32; i++){ r <<= 1; r |= (value >> i) & 1; } return r; } //两个相同的数异或为0,0异或任何数为任何数 int findOnly2(int arr[], int size) { assert(arr); assert(size > 0); int r = arr[0]; for (int i = 1; i < size; i++){ r ^= arr[i]; } return r; } //逆置 void reverse(char* pre, char* aft) { while (pre < aft){ *pre ^= *aft; *aft ^= *pre; *pre ^= *aft; pre++, aft--; } } //优化:先局部逆置,再整体逆置 //方法2 void reverseStr(char arr[]) { assert(arr); char *pre = arr; char *aft = pre; while (*aft){//局部逆置 pre = aft; while (*aft != ' ' && *aft != 0){ aft++; } reverse(pre, aft-1); aft++; } reverse(arr, pre);//整体逆置 } int main() { /*int num; scanf("%d", &num); printf("%x\n", reverse_bit(num));*/ /*int num1, num2; scanf("%d%d", &num1, &num2); printf("%f\n", AVERAGE(num1, num2)); printf("%d\n", AVERAGE2(num1, num2));*/ /*int arr[] = { 4, 5, 3, 8, 7, 2, 7, 2, 6, 4, 5, 3, 8 }; int size = sizeof(arr) / sizeof(arr[0]); printf("%d\n", findOnly2(arr, size));*/ char arr1[20] = { "student a am i" }; reverseStr(arr1); for (int i = 0; arr1[i]; i++){ printf("%c", arr1[i]); } system("pause"); return 0; }