2011-01-23 3 views
15

Можно создать дубликат:
Finding a single number in a listКоличество, которое происходит только один раз в массиве

Дан массив чисел, для одного числа всех остальных, за исключением, происходят дважды. Какой алгоритм должен найти этот номер, который встречается только один раз в массиве ?

Пример

a[1..n] = [1,2,3,4,3,1,2] 

должен вернуть 4

ответ

24

Пусть число, которое происходит только один раз в массиве будет x

x <- a[1] 
for i <- 2 to n 
    x <- x^a[i] 
return x 

С a^a = 0 и a^0 = a

Числа, которые происходят в паре сокращаются, и результат сохраняется в x

Рабочий код в С ++

#include <iostream> 

template<typename T, size_t N> 
size_t size(T(&a)[N]) 
{ 
    return N; 
} 
int main() 
{ 
    int a [] = {1,2,3,4,3,1,2}; 
    int x = a[0]; 
    for (size_t i = 1; i< size(a) ; ++i) 
    { 
     x = x^a[i]; 
    } 
    std::cout << x; 
} 
+1

@Prasoon: хорошее решение, Prasoon :-) – Nawaz

+0

@Nawaz: :) [.....] –

+0

@Prasoon: Кстати, это функция шаблона необходима? 'sizeof (a)/sizeof (a [0])' недостаточно? – Nawaz

19
  1. Создать новую int i = 0
  2. XOR каждый элемент с i
  3. После всех итераций будет ожидать число в i
+1

O__O Могу ли я спросить, как это решение было так очевидно для всех здесь? !! Я не мог подумать об этом за несколько дней ... – Mehrdad

+0

@Mehrdad: не знаю. Потому что это мелочи? – zerkms

+0

@zerkms: Вы имели в виду мелочи или тривиальные? В любом случае, хотя ... какие-либо рекомендации о том, как научиться думать о решениях подобных проблем, которые вы не видели раньше? (Думаю, вам нужно быть умным ... не уверен, что я умный, хотя. :() – Mehrdad

1

Well я знаю только грубой силы алгоритмом и он должен пройти через весь массив и проверить

код будет как (в C#):

k=0; 
for(int i=0 ; i < array.Length ; i++) 
{ 
    k ^= array[i]; 
} 
return k; 
0

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

Но более простым методом было бы установить двойные ключи в ноль или значение, которое невозможно в текущем формате. Также зависит от языка программирования, так как вы не можете изменять типы ключей в C++, в отличие от C#. Ответ

+0

Несколько решений O (n) на основе XOR уже опубликованы –

+0

Не существует способа определить, был ли ответ отправлен без перезагрузки страницы. Но это твоя правда. – Vlad

+0

фактически есть способ. Пока вы пишете ответ, и еще один ответ был отправлен - вы должны увидеть панель сверху о новой кнопке, чтобы загрузить их на текущую страницу (без перезагрузки). – zerkms

1

zerkms' в C++

int a[] = { 1,2,3,4,3,1,2 }; 

int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>()); 
2

Если у вас есть запасы, которые не могут быть разумно операции XOR (Big Целые или номера представлены в виде строк, например), альтернативный подход, который также является O (п), (но O (n) пространство, а не O (1) пространство) было бы просто использовать хеш-таблицу. Алгоритм выглядит следующим образом:

Create a hash table of the same size as the list 
For every item in the list: 
    If item is a key in hash table 
     then remove item from hash table 
     else add item to hash table with nominal value 
At the end, there should be exactly one item in the hash table 

Я хотел бы сделать код, C или C++, но ни один из них хэш-таблицы встроенный (Не спрашивайте меня, почему C++ не имеет хэш-таблицу в STL,. но имеет хэш-карту, основанную на красно-черном дереве, потому что я понятия не имею, о чем они думают.) И, к сожалению, у меня нет компилятора C# для проверки синтаксических ошибок, поэтому я даю вам Java-код. Однако это очень похоже.

import java.util.Hashtable; 
import java.util.List; 

class FindUnique { 
    public static <T> T findUnique(List<T> list) { 
     Hashtable<T,Character> ht = new Hashtable<T,Character>(list.size()); 
     for (T item : list) { 
      if (ht.containsKey(item)) { 
       ht.remove(item); 
      } else { 
       ht.put(item,'x'); 
      } 
     } 
     return ht.keys().nextElement(); 
    } 
} 
+0

Хешированные контейнеры находятся в предстоящем C++ 0x как 'std :: unordered_set' и' std :: unordered_map'. Текущие компиляторы уже имеют эти расширения TR1. – Blastfurnace

+0

Для полноты, хотя и не являющейся частью основного языка, если вы находитесь в системе POSIX, hcreate/hsearch доступен http://linux.die.net/man/3/hsearch – fayyazkl

Смежные вопросы