操作符刷题记录:交换两个变量、统计二进制中1的个数、求两个数二进制中不同位的个数、打印整数二进制的奇数位和偶数位、六进制转换、 序列中删除指定数字、 欧几里得(最大公约数)、递归走台阶etc

这篇博客探讨了位操作符的使用,包括右移、左移、按位与、按位或和按位异或,并通过实例展示了如何用它们来交换变量、统计二进制中1的个数、判断是否为2的幂次以及计算两个数二进制中不同位的个数。此外,还涵盖了从六进制转换、删除序列中的指定数字到计算最大公约数和最小公倍数的算法。
摘要由CSDN通过智能技术生成

操作符刷题记录

1. 下面哪个是位操作符:

在这里插入图片描述

  • 跟二进制位有关:

    >> << ~ & |
2. 下面代码的结果是:

在这里插入图片描述

3. 交换两个变量(不创建临时变量)
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    a = a ^ b;
    b = a ^ b;//b=a^b^b
    a = a ^ b;//a^b^a
    printf("a = %d b = %d\n", a, b);
    return 0; 
}
4. 统计二进制中1的个数

写一个函数返回参数二进制中 1 的个数。

比如: 15 0000 1111 4 个 1

a.法一:右移与1

在这里插入图片描述

int count_bit(int m)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (1 == ((m >> i) & 1))
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int num=count_bit(n);
	printf("%d\n", num);
    return 0;
}
a. apple 函数实现部分:
int count_bit(int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if ((n & 1) == 1)
			count++;
		n >>= 1;
	}
	return count;
}
b. 数学思想:商二余二运算

在这里插入图片描述

int count_bit(unsigned int n)
//不可以单纯写为int
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
			count++;
		n /=2;
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d",&n);
	//-1
	//11111111 11111111 11111111 11111111
	int num = count_bit(n);
	printf("%d\n", num);
	return 0;
}
c. 效率更高的做法:n&(n-1)

在这里插入图片描述

int count_bit(int m)
{
	int count = 0;
	while (m)
	{
		m = m & (m - 1);
		count++;
	}
	return count;
}
c. cake 判断一个数是不是2的n次方

在这里插入图片描述

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

编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?

输入例子:1999 2299

输出例子:7

5.1 主函数中实现
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((m >> i) & 1) != ((n >> i) & 1))
		{
			count++;
		}
	}
	printf("%d\n", count);
	return 0;
}
5.2 函数调用
int count_diff_bit(int m, int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((m >> i) & 1) != ((n >> i) & 1))
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);
	int i = 0;
	int count = count_diff_bit(m,n);
	printf("%d\n", count);
	return 0;
}
5.3 采用异或操作

异或操作的特点是:相同为0,相异为1。

0111

1010

1101(&)

int count_diff_bit(int m, int n)
{
	int ret = m ^ n;
	//m和n有多少个不同ret里就有多少个1
	int count = 0;
	while (ret)
	{
		ret = ret & (ret - 1);
		count++;
	}
	return count;
}
6. 下面代码的结果是:

在这里插入图片描述

同一个代码在不同编译器下有不同结果,说明程序的错误。

  • 转到反汇编(取消显示符号名):了解为何vs编译器结果为12

在这里插入图片描述

7. 下面代码的结果是:
  • 全局变量 不初始化 默认是 0
  • 局部变量 不初始化 默认是 随机值
  • 全局变量、静态变量是存放在静态区的。

在这里插入图片描述

8. 关于表达式求值说法不正确的是:

在这里插入图片描述

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

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

int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	//奇数位
	for (i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (n >> i) & 1);
	}
	printf("\n");
	//偶数位
	for (i = 31; i >= 1; i -= 2)
	{
		printf("%d ", (n >> i) & 1);
	}
	printf("\n");
	return 0;
}
10.上三角矩阵判定

在这里插入图片描述

#include<stdio.h>
int main()
{
    int n=0;
    scanf("%d",&n);
    int arr[n][n];
    int i=0;
    int j=0;
    //输入
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
    //判断
    int flag=1;//是上三角矩阵
    for(i=0;i<n;i++)
    {
        for(j=0;j<i;j++)
        {
           if(arr[i][j]!=0)
           {
               flag=0;
               goto end;
           }
        }
    }
end:
    if(flag==0)
        printf("NO\n");
    else
        printf("YES\n");
    return 0;
}
11. 六进制转换

在这里插入图片描述

#include<stdio.h>
int main()
{
    int n=0;
    scanf("%d",&n);
    int arr[20]={0};
    int i=0;
    while(n)
    {
        arr[i]=n%6;
        n/=6;
        i++;
    }
    for(--i;i>=0;i--)
    {
        printf("%d",arr[i]);
    }
    return 0;
}
12. 序列中删除指定数字

在这里插入图片描述

12.1 不算合理的做法
#include<stdio.h>
int main()
{
    int n=0;
    //输入n
    scanf("%d",&n);
    int i=0;
    int arr[n];
    //输入第二行
    for(i=0;i<n;i++)
    {
        scanf("%d",&arr[i]); 
    }
     //[1 2 3 4 5 9]
    //输入删除的数字
    int del=0;
    scanf("%d",&del);
   for(i=0;i<n;i++)
   {
       if(arr[i]!=del)
          printf("%d ",arr[i]);
   }
    return 0;
}
12.2 遍历数组:双指针、双下标的方式
int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int arr[n];
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	int del = 0;
	scanf("%d", &del);
	//i:遍历数组
	//j:存储元素
	i = 0;
	int j = 0;
	for (i = 0; i < n; i++)
	{
		if (arr[i] != del)
		{
			arr[j] = arr[i];
			j++;
		}
	}
	for (i = 0; i < j; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}
13. 欧几里得(最大公约数)

在这里插入图片描述

13.1 一般思路
int main()
{
    int n = 0;
    int m = 0;
    scanf("%d %d", &n,& m);
    int max = (n > m ? m : n);
    //假设最大公约数是n和m的较小值
    while (1)
    {
        if (n % max == 0 && m % max == 0)
            break;
        max--;
    }
    int min = (n > m ? m : n);
    //假设最小公倍数是n和m的较大值
    while (1)
    {
        if (min % n == 0 && min % m == 0)
            break;
        min++;
    }
    printf("%d\n", max + min);
    return 0;
}
13.2 辗转相除法
int main()
{
	long long n = 0;
	long long m = 0;
	scanf("%lld %lld", &n, &m);
	long long m2 = m;
	long long n2 = n;
	long long r = 0;
	//最大公约数
	while (r=n2%m2)
	{
		n2 = m2;
		m2 = r;
	}
	//最小公倍数:m*n/最大公约数
	printf("%lld\n", m * n / m2 + m2);
	return 0;
}
14. 走台阶

每次可以选择走一阶或者走两阶,一共有多少种走法?

在这里插入图片描述

int walk(int n)
{
    if (n <= 2)
        return n;
    else
        return walk(n - 1) + walk(n - 2);
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = walk(n);
    printf("%d\n", ret);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值