蓝桥杯-第一章-位运算

这是一个关于位运算的文章,在学习过程中发现位运算的作用很奇妙,有些不容易观察出来的东西,利用位运算却能很轻松的解决

**

1. 求出一个十进制数的二进制形式中1的个数

**

思路:原理就是利用 & 运算时1 & 1为真其余为假的大原理。
每检测一次让这个数往右移动一位,然后与1做 & 运算,如果是1则说明这个数的这个位上面是1,则将计数器加1,否则继续循环直到这个数右移变为0.代码实现如

    #include <stdio.h>
    int main()
    {
     int n = 0, num = 0, t = 0;
     printf("请输入一个数字,然后会输出它的二进制里有几个1\nn = ");
     scanf("%d",&n);
     t = n;
     while(n != 0)
     {
      if(n & 1 == 1)
      num++;
n= n>>1;
     }
     printf("%d里面有%d个1\n",t,num);
     return 0;
    }

2.从已知范围的数里找出唯一一个出现两次的数。

例:有1001个数范围是0-999只有一个数出现两次其他数均只出现了一次。求出这个数。

思路:

位运算的异或运算可以消去一堆数里面出现偶次的数。即x ^ a ^ a = x.

又因为已知数的范围,所以可将该题演变为将该范围的所有数出现为偶次,而目标数字出现了奇数次。即先用一个为0的变量x与0-999的所有数字进行异或操作。这步就是先保证将所有数字出现一次。

再将这所有的数字与x进行异或操作。这下就可以消除出现一次的数并保留下出现两次的数了。

(找出落单的数直接异或操作输出即可)

代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

void show(int a[], int N);

int main()

{

    int N = 11, x = 0, number = 0;

    int *a;

    a = (int *)calloc(N,sizeof(int));

    int i = 0;

    for(i = 0; i<N-1; i++)

        a[i] = i+1;

    srand(time(NULL));

    //show(a,N);

    number = rand() % (N-1)+1;

    a[N-1] = number;

    show(a,N);

    x= 0;

    for(i = 1; i <= N-1; i++)

        x = x^i;

    for(i = 0; i< N; i++)

        x = x^a[i];

    printf("%d\n",x);

    return 0;

}

void show(int a[], int N)

{

    int i = 0;

    for(i = 0; i < N; i++)

        printf("%d%c",a[i],i == N-1?'\n':' ');

}

3.判断一个数是不是2的整数次幂

思路:写出2的整数次幂可以发现,2的整数次幂都是在最高位为1,其余为0.

再写出它的后一位。

比如8和7

8的二进制是1000

7的二进制是0111.

再比如16和15

16的二进制是10000

15的二进制是01111

可以发现2的整数次幂的数和它减一的数做&运算的话,结果始终为0.

则可以利用此特点找出二的整数次幂,代码实现如下。

//以0为测试结束的标志 

#include <stdio.h>

int main()

{

    int n = 0;

    printf("请输入一个数,然后会输出它是不是2的整数次幂\nn
= ");

    while(scanf("%d",&n)!=EOF)

    {

        if(n == 0)

        break;

        if((n & (n-1) )== 0)

        printf("YES\n");

        else 

        printf("NO\n");

        printf("请输入一个数,然后会输出它是不是2的整数次幂\nn
= ");

    }

    return 0; 

}

4.将整数的奇偶位互换

思路:还是利用 & 运算,因为int数据类型的数只有32位,

所以只要

利用一个所有偶数位上为1而奇数位为0的数和该数做 & 运算就可以取得偶数位上的数,同样奇数位只需要一个所有奇数位上为1而偶数位为0的数和该数做 & 运算就可以取得这个数的奇数位。

最后再把偶数右移一位,奇数左移一位即可。

代码实现如下

#include <stdio.h>

int main()

{

 int i = 0,a=0;

int ou=0,ji=0;

printf("请输入一个数将输出它的奇数位和偶数位调换前后的数\ni = "); 

scanf("%d",&i);

ou = i&0xaaaaaaaa;

ji = i&0x55555555;

a = ou ^ ji;

printf("奇偶转换之前 = %d\n",a);

a = (ou>>1)^(ji<<1);

printf("奇偶转换过后 = %d\n",a);

}

5.乘二挪整,二进制表示浮点整数。

代码实现如下

#include <stdio.h>

#define max 34

int main()

{

    double n = 0, t = 0;

    int i = 0, num = 0;

    int a[max]= {0};

    printf("请输入一个实数\nn = ");

    scanf("%lf",&n);

    t = n;

    //乘二挪整

    while( t )

    {

        t*=2;

        if(t >= 1)

        {

           a[i] = 1;

           t -= 1;

        }

        else

           a[i] = 0;

        i++;

    }

    num = i-1;

    //printf("num = %d\n",num);

    if(num > 32)

        printf("ERROR\n");

    else

    {

        printf("0.");

        for(i = 0; i <= num; i++)

           printf("%d",a[i]);

    }

    return 0;

}

猜你喜欢

转载自blog.csdn.net/CSDNsabo/article/details/91476769
今日推荐