进制练习题【找出只出现一次的数字、交换两个变量(不创建临时变量)、统计二进制中1的个数、打印整数二进制的奇数位和偶数位、求两个数二进制中不同位的个数】

找出只出现一次的数字

在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。例如:数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5

思路:0 ^ n = n 、n ^ n = 0、通过异或算出最后的结果,1^2^3^4^5^1^2^3^4相当于1^1=0、2^2=0、3^3=0、4^4=0、结果就为5

cpp 复制代码
#include <stdio.h>

int f(int arr[], int len)
{
    int ret = 0;
    int i = 0;
    for (i = 0; i < len; i++)
    {
        ret ^= arr[i];
    }
    return ret;
}
int main()
{
    int arr[] = { 1,2,3,4,5,1,2,3,4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    int dog = f(arr, len);
    printf("%d\n", dog);

    return 0;
}

交换两个变量(不创建临时变量)

不允许创建临时变量,交换两个整数的内容

方法一

思路:通过异或交换

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//不允许创建临时变量,交换两个整数的内容
int main() {
	int a = 5;
	int b = 1;
	//0101^0001
	a = a ^ b;//0100  4
	//0100^0001
	b = a ^ b;//0101  5
	//0100^0101
	a = a ^ b;//0001  1

	return 0;
}

方法二

思路:通过加减法交换

不推荐,可能会整数溢出,因为整数较大时a+b可能会超出整数的范围

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//不允许创建临时变量,交换两个整数的内容
int main() {
	int a = 5;
	int b = 1;
	a = a + b;
    b = a - b;
    a = a - b;

	return 0;
}

统计二进制中1的个数

写一个函数返回参数二进制中 1 的个数,比如: 15 0000 1111 4 个 1

二进制中1的个数_牛客题霸_牛客网

方法一

思路: 循环进行以下操作,直到n被缩减为0:

1. 用该数据模2,检测其是否能够被2整除

2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1 3. 如果n不等于0时,继续1

cpp 复制代码
int NumberOf1(int n) {
    // 15    0000 1111    4 个 1
    int count = 0;
    unsigned int un = (unsigned int)n;
    while (un != 0) {
        if (un % 2 == 1) {
            count++;
        }
        un = un / 2;
    }
    return count;
}

方法二

方法一效率低

思路: 一个int类型的数据,对应的二进制一共有32个比特位,可以采用位运算的方式一位一位的检测

cpp 复制代码
int NumberOf1(unsigned int n)
{
	int count = 0;
	int i = 0;
	for(i=0; i<32; i++)
	{
		if(((n>>i)&1) == 1)
			count++;
	}
	return count;
}

方法三

方法二效率也低,因为每回都要循环32次

思路:用相邻的两个数据进行按位与运算

cpp 复制代码
int NumberOf1(int n)
{
	int count = 0;
	while(n)
	{
		n = n&(n-1);
		count++;
	}
	return count;
}

打印整数二进制的奇数位和偶数位

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

思路:打印相应位数的数,一个二进制通过右移再&1

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
void NumberOf1(int n) {
    printf("偶数位");
    for (int i = 31; i >= 1; i -= 2) {
        printf("%d", (n >> i) & 1);
    }
    printf("\n");
    printf("奇数位");
    for (int i = 30; i >= 0; i -= 2) {
        printf("%d", (n >> i) & 1);
    }
}
int main() {
    int n = 0;
    scanf("%d", &n);
    NumberOf1(n);
    return 0;
}

求两个数二进制中不同位的个数

两个整数二进制位不同个数_牛客题霸_牛客网

思路:先用异或算出两个数找不同的结果的值,再把这个值存入temp,然后利用循环,只要temp不是0的时候就执行循环体,用**temp & (temp-1)**把temp里面有多少个1算出来,其中的逻辑是每&一次少一个1,这样就循环一次算出一个1,把每次循环算出来的1存入count里

cpp 复制代码
#include <stdio.h>

int main() {
    int a, b;
    while (scanf("%d %d", &a, &b) != EOF) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to 
        int count = 0;
        int temp = a ^ b;
        while(temp){
            count++;
            temp = temp & (temp - 1);
        }
        printf("%d\n", count);
    }
    return 0;
}
相关推荐
INS_KF7 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
淡海水8 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
leobertlan8 小时前
好玩系列:训练一个神经网络模型指导小孩玩游戏2-大局观教练
算法
CS_Zero8 小时前
C语言sizeof是函数吗?
c语言·开发语言
Tisfy9 小时前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯
tju新生代魔迷9 小时前
Verilog HDL 学习笔记(十三)| 第13章 编程语言接口(PLI)
笔记·学习
乐迪信息9 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
kiracrimson10 小时前
从缓存的角度看链表与线性表的差异
数据结构·链表·缓存
点心的游戏开发世界10 小时前
UnityShaderGraph滚动UV笔记
笔记·uv
瑞码空间10 小时前
git知识点黄金笔记
笔记·git·elasticsearch