2012-05-26 47 views
7

Tôi gặp một bài đăng How to find a duplicate element in an array of shuffled consecutive integers? nhưng sau đó nhận ra rằng điều này không thành công đối với nhiều đầu vào.Sử dụng toán tử XOR để tìm các phần tử trùng lặp trong một mảng không thành công trong nhiều trường hợp

Đối với ví dụ:
arr[] = {601,602,603,604,605,605,606,607}

#include <stdio.h> 
int main() 
{ 
int arr[] = {2,3,4,5,5,7}; 
int i, dupe = 0; 
for (i = 0; i < 6; i++) { 
    dupe = dupe^a[i]^i; 
} 
printf ("%d\n", dupe); 
return 0; 
} 

Làm thế nào tôi có thể sửa đổi mã này để các yếu tố trùng lặp có thể được tìm thấy cho tất cả các trường hợp?

+0

Tôi đã xem qua bài đăng nói về bù trừ mà tôi không thể hiểu được http://stackoverflow.com/questions/8018086/xor-to-find-duplicates-in-an-array Ai có thể đề xuất điều gì đó .. ?? – Snehasish

Trả lời

16

Từ câu hỏi ban đầu:

Giả sử bạn có một mảng của 1001 số nguyên. Các số nguyên theo thứ tự ngẫu nhiên, nhưng bạn biết từng số nguyên nằm trong khoảng từ 1 đến 1000 (bao gồm). Ngoài ra, mỗi số chỉ xuất hiện một lần trong mảng, ngoại trừ một số, xuất hiện hai lần.

Nó về cơ bản nói, thuật toán mà chỉ có tác dụng khi bạn có số nguyên liên tiếp, bắt đầu với 1, kết thúc với một số N.

Nếu bạn muốn thay đổi nó cho trường hợp tổng quát hơn, bạn phải làm những điều sau:

Tìm tối thiểu và tối đa trong mảng. Sau đó tính toán đầu ra mong đợi (xor tất cả các số nguyên giữa tối thiểu và tối đa). Sau đó tính toán xor của tất cả các phần tử trong mảng. Sau đó xor này hai điều và bạn sẽ có được một đầu ra.

+1

Xem xét arr [] = {2, 3, 5, 5, 7}, sau đó min = 2 và max = 7 Đầu ra dự kiến ​​= 2^3^4^5^6^7 = 1 XOR của tất cả các phần tử trong mảng = 2^3^5^5^7 = 6 XOR của 1 và 6 = 1^6 = 7 !!!!! không phải là câu trả lời bắt buộc !!!!! – Snehasish

+2

{2, 3, 5, 5, 7} không phải là một mảng các phần tử liên tiếp. Liên tiếp có nghĩa là các số khác nhau một, vì vậy nếu một số bị trùng lặp thì đầu vào tốt là dành cho ví dụ {2, 3, 3, 4, 5, 6, 7}. Trong trường hợp chung của bạn, không có giải pháp đơn giản. Bạn cần phân ngẫu nhiên (bảng băm) hoặc sắp xếp để nhận câu trả lời. – usamec

1

Đây là mã được hiển thị trong câu hỏi gốc, khác với việc triển khai của bạn. Bạn đã sửa đổi nó để sử dụng một biến địa phương thay vì thành viên cuối cùng của mảng, mà làm cho một sự khác biệt:

for (int i = 1; i < 1001; i++) 
{ 
    array[i] = array[i]^array[i-1]^i; 
} 

printf("Answer : %d\n", array[1000]); 
+0

Nó hoạt động cho trường hợp được đưa ra trong câu hỏi đó ... nhưng đối với các trường hợp thử nghiệm như {1, 2, 10, 11, 5, 6, 8, 5} và {601,602,603,604,605,605,606,607} nó mang lại kết quả lạ !!!! – Snehasish

7

Tuyên bố XOR có thuộc tính 'a' XOR 'a' sẽ luôn là 0, nghĩa là chúng hủy, vì vậy, nếu bạn biết rằng danh sách của bạn chỉ có một bản sao và phạm vi đó là x thành y , 601 đến 607 trong trường hợp của bạn, có khả năng giữ xor của tất cả các phần tử từ x thành y trong một biến, và sau đó xor biến này với tất cả các phần tử bạn có trong mảng của bạn. Vì sẽ chỉ có một phần tử sẽ được nhân đôi nó sẽ không bị hủy bỏ do hoạt động xor và đó sẽ là câu trả lời của bạn.

void main() 
{ 
    int a[8]={601,602,603,604,605,605,606,607}; 
    int k,i,j=601; 

    for(i=602;i<=607;i++) 
    { 
     j=j^i; 
    } 

    for(k=0;k<8;k++) 
    { 
     j=j^a[k]; 
    } 

    printf("%d",j); 
} 

Mã này sẽ cho đầu ra 605, như mong muốn!

+1

Nó chỉ hoạt động khi tất cả các phần tử giữa x và y có mặt. Hãy xem xét trường hợp arr [] = {601, 602, 603, 603, 604, 606} Chạy nó sẽ cho đầu ra kỳ lạ !!!! – Snehasish

+1

rõ ràng, và tôi đã làm rõ ràng trong câu trả lời của chính tôi! Các nhà điều hành XOR có chức năng riêng của mình, bạn không thể làm cho nó hoạt động theo mong muốn của bạn! – Ashwyn

+0

Tốt nhất, bạn phải biết các phần tử hiện diện trong mảng, (trùng lặp hoặc không) và xor với tất cả các phần tử đó, ví dụ, lúc đầu, bạn lấy int i = 601^602^603^603^604^606, bây giờ xor này với các yếu tố mà mảng được cho là có chứa (bạn vẫn không biết trong số đó được nhân đôi), đó là, tôi^601^602^603^604^606. Đầu ra phải là 603! – Ashwyn

1
//There i have created the program to find out the duplicate element in array. Please edit if there are required some changes. 
int main() 
{ 
    int arr[] = {601,602,603,604,605,605,606,607}; 
    //int arr[] = {601,601,604,602,605,606,607}; 
    int n= sizeof(arr)/sizeof(arr[0]); 

    for (int i = 0; i < n; i++) 
    { 
     for (int j = i+1; j < n; j++) 
     { 
      int res = arr[i]^arr[j]; 

      if (res == 0) 
      { 
       std::cout<< "Repeated Element in array = "<<arr[i]<<std::endl; 
      } 
     } 
    } 
    return 0; 
} 

// HOẶC Bạn có thể sử dụng Hashtable và hàm Hash khi bạn nhập vào cùng một giá trị
vào bảng băm thời gian mà bạn có thể làm cho số lượng lớn hơn nếu
một giá trị của nó ở chỉ số cụ thể của HashTable sau đó bạn có thể nói rằng có giá trị lặp lại trong mảng.