Использование оператора XOR для поиска повторяющихся элементов в массиве во многих случаях не удается

я наткнулся на сообщение как найти дубликат элемента в массиве перетасованных последовательных целых чисел? но позже понял, что это не удается для многих входных данных.

например:
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 ("%dn", dupe);
return 0;
}

Как я могу изменить этот код, чтобы дубликат элемента можно было найти для всех случаев ?

4 ответов


из первоначального вопроса:

предположим, что у вас есть массив из 1001 целых чисел. Целые числа находятся в случайном порядке, но вы знаете, что каждое из целых чисел находится между 1 и 1000 (включительно). Кроме того, каждое число появляется только один раз в массиве, за исключением одного числа, которое встречается дважды.

Он в основном говорит, что алгоритм работает только тогда, когда у вас есть последовательные целые числа,начиная с 1, заканчивая какой-Н

Если вы хотите чтобы изменить его на более общий случай, вы должны сделать следующие вещи:

найти минимум и максимум в массиве. Затем вычислите ожидаемый результат (xor все целые числа между минимумом и максимумом). Затем вычислите xor всех элементов в массиве. Затем xor это две вещи, и вы получите выход.


оператор XOR имеет свойство, что " A " XOR " a " всегда будет 0, то есть они отменяются, таким образом, если вы знаете, что ваш список имеет только один дубликат и что диапазон, скажем, x к y, 601 к 607 в вашем случае, возможно сохранить xor всех элементов от x до y в переменной, а затем xor эту переменную со всеми элементами, которые у вас есть в вашем массиве. Так как там будет только один элемент, который будет повторяться он не будет отменен из-за операции XOR и это будет ответ.

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);
}

этот код даст выход 605, по желанию!


вот код, показанный в исходном вопросе, который отличается от вашей реализации. Вы изменили его, чтобы использовать локальную переменную вместо последнего члена массива, что имеет значение:

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

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

//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;  
}  

/ / или вы можете использовать хэш-таблицу и хэш-функцию при вводе того же
значение в хэш-таблице, что время вы можете сделать счет, если его больше, чем
одно значение в определенном индексе HashTable, тогда вы можете сказать, что в массиве есть повторяющееся значение.