位操作符练习

    xiaoxiao2025-01-17  18

    1.编写函数: unsigned int reverse_bit(unsigned int value); 这个函数的返回值是value的二进制位模式从左到右翻转后的值。 解题思路 已知题目要求将整数的2进制位模式进行翻转,因此可以用位操作符,一次判断每一位是否为1。要求将二进制翻转,则第一个将会移动到第32位比特位上,因此新申请一个变量来保存这个新生成的数字,依次类推,第二位若为1,将其保存到第31位上,可用for循环完成,每位加上其2进制的权重,将其转化为10进制保存,最后返回该值,则为所得结果。

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<math.h> unsigned int reverse_bit(unsigned int value) { unsigned int sum = 0; int i = 0; for (i = 0; i < 32; i++) { if (((value >> i) & 1) == 1) sum += pow(2, (32 - i - 1)); } return sum; } int main() { int num = 0; int ret = 0; printf("请输入一个数字:"); scanf("%d", &num); ret = reverse_bit(num); printf("逆转后:%u\n", ret); system("pause"); return 0; }

    2.不使用(a+b)/2这种方式,求两个数的平均值。 解题思路 不适用a+b是防止数据溢出,另一种方法为a,b做差,但当a或b其中一个为负数是就还是有出现a+b的情况。 因此我们可以选择a,b异或,所得结果的二进制位若为1,表示为该2个数字不一样的2进制位,以3(011)和5(101)为例:异或结果为110,则表示3和5在第二位第三位比特位上不同,若2个数异或结果为0则表示该两个数不存在差异,也就不存在差值。 以此我们可以判断2个数字的差值。首先判断所异或的结果110的每一个为1还是为0,为0,则不进行判断,若为1,判断,该差异是由3造成的还是由5造成的,然后规定若是5造成的我们按照正数保存,3造成的用负数保存,最后所得到的数字即为5与3的差值,依次得到的结果可认为为第一个数字减第二数的差值,以此来得到2个数字的平均值。 不足:只能解决同为整数或同为负数的问题,无法解决一整一负的情况

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<math.h> int main() { int a = 5; int b = 3; int c = a^b; int i = 0; int sum = 0; for (i = 0; i < 32; i++) { if (((c >> i) & 1) == 1) { if (((a >> i) & 1) == ((c >> i) & 1)) sum += pow(2, i); if (((b >> i) & 1) == ((c >> i) & 1)) sum -= pow(2, i); } } printf("平均值:%d", a-sum/2); system("pause"); return 0; }

    3.编程实现: 一组数据中只有一个数字出现了一次。 其他所有数字都是成对出现的。 请找出这个数字。(使用位运算) 解题思路 已知数据只有一个数据出现了一次,其他都是成对出现,则已知2个相同的数字异或结果为0,任何数字异或0,结果为自己本身,因此可以将这组数据全部异或起来,最后所得的结果为所找的数据。

    int main() { int i = 0; int sum = 0; int arr[10] = { 1, 3, 2, 5, 5, 3, 2, 7, 1 }; for (i = 0; i < 9; i++) { sum ^= arr[i]; } printf("%d", sum); system("pause"); return 0; }

    有一个字符数组的内容为:“student a am i”, 请你将数组的内容改为"i am a student". 要求: 不能使用库函数。 只能开辟有限个空间(空间个数和字符串的长度无关)。 解题思路 观察该字符串可以发现,在大体上字符串全部逆序,但每个空格所隔开的字符串并未逆序,因此我们可以将字符串全体逆序,之后再将每个空格隔开的内容再次逆序,这样2次逆序之后,空格所隔开的内容并未发生改变。 用第一次循环将所有字符串逆序 然后在此检索字符串,判断每个空格之间的下标,将其下标开始到结束的位置的内容进行逆序 程序实现

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> void Print(char arr[],int len) { char tmp = 0; int head = 0; int last = 0; int flag = 0; int i = 0; int l = len - 1; int r = 0; while (r <= l) { tmp = arr[r]; arr[r] = arr[l]; arr[l] = tmp; r++; l--; } //printf("%s", arr); while (head < len) { while (arr[flag] != ' '&&arr[flag] != '\0') { flag++; } last = flag - 1; while (head <= last) { tmp = arr[head]; arr[head] = arr[last]; arr[last] = tmp; head++; last--; } flag++; head = flag; last = flag; } printf("%s", arr); } int main() { char arr[50] = { 0 }; printf("请输入字符串(50个以内):"); gets(arr); int len = strlen(arr); Print(arr, len); printf("\n") system("pause"); return 0; }
    最新回复(0)