进制练习题【找出只出现一次的数字、交换两个变量(不创建临时变量)、统计二进制中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;
}
相关推荐
灯厂码农2 小时前
C语言内存管理——内存对齐与共用体union
linux·服务器·c语言
RainCity3 小时前
Java Swing 自定义组件库分享(十三)
java·笔记·后端
QiLinkOS3 小时前
第三视觉理解徐玉生与他的商业活动(28)
大数据·c++·人工智能·算法·开源协议
wabs6663 小时前
关于动态规划【力扣1143.最长公共子序列的思考】
算法·leetcode·动态规划
剑挑星河月4 小时前
54.螺旋矩阵
java·算法·leetcode·矩阵
伏 念4 小时前
AI Coding 零基础实战教程
c语言·进程·预处理
你家人养牛4 小时前
OOC Relation Plugin:C 语言面向对象 开发的高效辅助工具
c语言·vscode
Robot_Nav4 小时前
MPPI 局部规划器实验设计讲解
人工智能·算法·mppi
想你依然心痛4 小时前
嵌入式C代码规范:MISRA-C 2012核心规则解读——类型安全与未定义行为深度剖析
c语言·安全·代码规范