動態

詳情 返回 返回

操作符題目練習 - 動態 詳情

1 單身狗

在一個整型數組中,只有一個數字出現一次,其他數組都是成對出現的,請找出那個只出現一次的數字。

例如:數組中有:1 2 3 4 5 1 2 3 4,只有5出現一次,其他數字都出現2次,找出5


需要用到的知識:

按位異或 ^ 將其第一操作數的每個位(補碼)與其第二操作數的相應位進行比較。如果其中一個操作數中的位為 0,而另一個操作數中的位為 1,則相應的結果位設置為 1(即標記不同)。 否則,將對應的結果位設置為 0。(該運算符的兩個操作數必須為整型類型

按位異或運算有以下有趣的特點:

//1. a ^ a = 0
//2. 0 ^ a = a
//3. 3 ^ 3 ^ 5 = 5
//   3 ^ 5 ^ 3 = 5  即支持交換律

由於數組中除5外其他數字均成對出現,而按位異或運算中相同數字的結果為0,我們可以利用這一特性找出單獨的數字。

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Func(int arr[], int len)
{
    int ret = 0;
    for (int i = 0; i < len; i++)
    {
        ret ^= arr[i];//對arr數組的每一個值,按位異或
    }
    return ret;
}

int main()
{
    int arr[] = { 1,2,3,4,5,1,2,3,4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    printf("%d\n", Func(arr, len));
    return 0;
}

運行結果:

2 交換兩個變量(不創建臨時變量)

不允許創建臨時變量,交換兩個整數的內容


需要用到的知識:

先演示一種方法。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a = 1;
    int b = 5;
    printf("交換前:%d %d\n", a, b);
    a = a + b;//可能溢出
    b = a - b;//b = (a + b) - b = a
    a = a - b;//a = (a + b) - a = b
    printf("交換後:%d %d\n", a, b);
    return 0;
}

由於存在a = a + b,當ab的值過大時可能會溢出。按位異或 **^**能很好的解決這個問題,因為其直接操作的是ab的二進制碼。(提醒:這種方法只能針對整數交換且可讀性不高、效率不高)

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a = 1;
    int b = 5;
    printf("交換前:%d %d\n", a, b);
    a = a ^ b;
    b = a ^ b;//b = (a ^ b) ^ b = a
    a = a ^ b;//a = (a ^ b) ^ a = b
    printf("交換後:%d %d\n", a, b);
    return 0;
}

運行結果:

3 統計二進制中1的個數

寫一個函數返回參數二進制中 1 的個數。

比如: 15 0000 1111 4個1


需要用到的知識:按位與&移位操作符<<>>

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//法1
int main()
{
    int num = 15;
    int count = 0;
    for (int i = 0; i < 32; i++)
    {
        if ((num >> i) & 1)
            count++;
    }
    printf("%d\n", count);
    return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//法2
int main()
{
    int num = 15;
    int count = 0;
    while (num)
    {
        count++;
        num = num & (num - 1);//關鍵點
    }
    printf("%d\n", count);
    return 0;
}

4 二進制位置0或者置1

編寫代碼將13二進制序列的第5位修改為1 ,然後再改回0

13 的 2 進制序列:   00000000 00000000 00000000 00001101
將第 5 位置為 1 後: 00000000 00000000 00000000 00011101
將第 5 位再置為 0 : 00000000 00000000 00000000 00001101

需要用到的知識:按位與&按位或|按位取反~移位操作符<<>>

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a = 13;
    a = a | (1 << 4);
    printf("%d\n", a);
    a = a & ~(1 << 4);
    printf("%d\n", a);
    return 0;
}

5 打印整數二進制的奇數位和偶數位

獲取一個整數二進制序列中所有的偶數位和奇數位,分別打印出二進制序列


需要用到的知識:按位與&移位操作符<<>>

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a = 13;
    //13  00000000 00000000 00000000 00001101
    //1   00000000 00000000 00000000 00000001
    printf("13的二進制偶數位:");
    //    0010
    for (int i = 31; i >= 0; i-=2)
    {
        printf("%d ", (a>>i) & 1);
    }
    printf("\n");
    printf("13的二進制奇數位:");
    //    0011
    for (int i = 30; i >= 0; i -= 2)
    {
        printf("%d ", (a >> i) & 1);
    }
    printf("\n");
    return 0;
}

6 求兩個數二進制中不同位的個數

編程實現:兩個int(32位)整數m和n的二進制表達中,有多少個位(bit)不同?

輸入例子:1999 2299

輸出例子:7


需要用到的知識:按位異或 ^按位與&第3題

代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int a = 1999;
    int b = 2299;
    int c = a ^ b;
    int count = 0;
    while (c)
    {
        count++;
        c = c & (c - 1);
    }
    printf("%d\n", count);
    return 0;
}

正文完

user avatar java_study 頭像 zbooksea 頭像 laoshideyangrouchuan 頭像 reddish 頭像 timeofsunrise 頭像 wanlanqiudehuoche_ej0yz4 頭像 sw7cc 頭像 javageek 頭像 neteaseyunxin 頭像 jizaodebangbangtang 頭像 mangrandedanche 頭像 jixingsuiyuan 頭像
點贊 13 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.