一個數組中只有兩個數字是出現一次的,其他的數字都出現了兩次,找出這兩個數字,編寫程式。
阿新 • • 發佈:2019-01-05
本題的最關鍵之處就是巧用兩個數異或得到的二進位制中“1”單位位數
程式碼如下:
方法一:
#include<stdio.h> int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 5, 6 }; int i = 0; int ret = 0; int pos = 0; int num1 = 0; int num2 = 0; //1.把所有數字異或 for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { ret ^= arr[i]; } //2.找ret二進位制中為1的數 for (i = 0; i < 32; i++) { if (((ret >> i) & 1) == 1) { pos = i; break; } } //分組 for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (((arr[i] >> pos) & 1) == 1) { num1 ^= arr[i]; } } num2 = num1^ret; printf("num1=%d,num2=%d\n", num1, num2); return 0; }
方法二:
#include<stdio.h> void find_two_diff_num(int arr[], int sz, int *p1, int *p2) { int i = 0;//迴圈變數 int ret = 0; int pos = 0; *p1 = 0;//數字1的地址 *p2 = 0;//數字2 的地址 //1.把所有數字異或 for (i = 0; i < sz; i++) { ret ^= arr[i];//迴圈到最後一次的結果是5^6,即就是101^110=011 } //2.找ret二進位制中為1的一位 for (i = 0; i < 32; i++) { if (((ret >> i) & 1) == 1)//上一步兩個數異或的後兩位為1 { pos = i; break; } } //分組 for (i = 0; i < sz; i++) { if (((arr[i] >> pos) & 1) == 1) { (* p1) ^= arr[i]; } } (*p2) = (*p1) ^ ret; } int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 5, 6 }; int sz = sizeof(arr) / sizeof(arr[0]);//陣列大小 int num1 = 0;//數字1 int num2 = 0;//數字2 find_two_diff_num(arr, sz, &num1, &num2); printf("num1=%d,num2=%d\n", num1, num2); return 0; }
執行結果: