1. 程式人生 > >一個數組中只有兩個數字是出現一次,其他所有數字都出現了兩次。找出這兩個數字

一個數組中只有兩個數字是出現一次,其他所有數字都出現了兩次。找出這兩個數字

方法1:遍歷,查詢

定義一個臨時變數k=0,不斷將陣列每個數與陣列每個元素比較,如果兩個數相等k++,然後判斷k是否等於1。如果為1,則這個數在陣列只出現一次;如果k=2,說明出現兩次。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
void find_num(int arr[], int sz)
{
    int i, j, k = 0;
    for (i = 0; i < sz; i++)
    {
        k = 0;
        for (j = 0
; j < sz; j++) { if (arr[j] == arr[i]) k++; } if (k == 1) printf("單數為 %d\n", arr[i]); } printf("\n"); } int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3, 5 }; int sz = sizeof(arr) / sizeof(arr[0]); find_num(arr, sz); system("pause"
); return 0; }

方法2:
思路:
陣列不全成對出現,有2個單數。 {3,5,7,3,5,11}
此時,每個數依次異或的結果為:0011^0101^0111^0011^0101^1011=1100。
因為後邊兩位是0,則說明兩個單數是從倒數三位不同的。然後讓每個數右移兩位 則資料會變為
3: 0000
5: 0001
7: 0001
3: 0000
5: 0001
11:0010
然後把末尾為零的依次異或 在這組資料裡是3 3 11; 結果得到單數11。
把末尾為1的依次異或 在這組資料裡是5 7 5;結果得到單數7。

void find_num(int *p, int sz)
{
    int
i = 0; int n = 0; int count = 0; int num1 = 0; int num2 = 0; for (i = 0; i < sz;i++)//將所有數異或 { n ^= *(p + i); } while (!(n & 1))//判斷異或結果有多少個0 { count++; n >>= 1; } for (i = 0; i < sz; i++) { n = *(p + i) >> count; //所有數異或結果後面有幾個0, //每個數依次往右移動幾位 if (n & 1) num1 ^= *(p + i); //把末位為1的數依次異或 else num2 ^= *(p + i); //把末位為0的數依次異或 } printf("兩個單數為 %d %d\n", num1, num2); } int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3, 5 }; int sz = sizeof(arr) / sizeof(arr[0]); find_num(arr, sz); system("pause"); return 0; }