Поиск одинаковых элементов в двух массивах

Тема в разделе "WASM.RESEARCH", создана пользователем gorodon, 18 окт 2011.

  1. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Есть 2 больших массива A[N] и B[M], в каждом из которых есть по одному одинаковому элементу, т.е.

    A[x] = B[y]

    0 <= x < N
    0 <= y < M

    необходимо найти x и y.

    Подскажите методы быстрого нахождения x и y.
    Полный перебор N*M категорически неприемлем... Может кто у Кнута встречал?
     
  2. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    Либо сортировка, либо нужна доп. информация о размере массива и диапазоне значений элементов, может тогда что-то придумается
     
  3. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Имхо, поразрядная сортировка и дальнейший линейный поиск (сравнили A`[1] в B`[1], где вышло меньше, по тому массиву идём далее, пока не натыкаемся на бóльшее число, тогда меняем массив по которому ходим — ну и так далее, пока нет равенства).

    Или O(N+M) доп. памяти у нас тоже нет?
     
  4. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Элемент массива представляет собой объект длиной в n байт в общем случае (от 4 до 256), диапазон значений - любой, размеры массивов - по несколько миллионов элементов...
     
  5. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    Ну да похоже что варианта лучше чем сортировка за NlogN а потом поиск за N не придумать
     
  6. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    при точном поиске и достаточной памяти - хэш табл
     
  7. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Вообщем, так пока и реализовал:
    -выделение памяти под массив C[N+M], копирование элементов из А,В в С - (N+M)
    -быстрая сортировка за - K1*(N+M)*log(N+M)
    -поиск в массиве C[N+M] двух одинаковых, рядом стоящих элементов - (N+M)
    -если элементы найдены в пред-м пункте, то поиск номеров x и y в A и B - (N+M)

    qqwe
    Если
    быстрее вышеописанного, то дайте ссылку, плиз.
     
  8. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    какой-такой ссылки? разве не знать хэш таблицы? почему не хотеть читать про хэш таблицы в гугле?

    (абиделись? - лучше делайте как хотите)
     
  9. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    Ну можно ещё конечно поюзать хеш и сделать такой вариант
    Код (Text):
    1. boolean flags[P] = {false};
    2. for_each(x in A)
    3. {
    4.    flags[hash(x)] = true;
    5. }
    6. for_each(y in B)
    7. {
    8.    if (flags[hash(y)])
    9.    {
    10.       for_each(x in A)
    11.       {
    12.          if(x=y)
    13.          {
    14.              printf "found element!";
    15.          }
    16.       }
    17.    }
    18. }
    Получается, что если условие 'if (flags[hash(y)])' будет не часто срабатывать, то поиск будет быстрым.... Значит, получается вариант с сортировкой оценивается как O((N+M)*log(N+M)), а с хешем как O(K*(N+M)), где K - количество срабатываний условия flags. Если K больше чем log(N+M), то вариант с сортировкой лучше, иначе лучше сортировка.
    Попытаемся оценить K. Будем считать, что вероятность срабатывания условия равна отношению количества true-элементов (TL) в массиве flags к общему количеству элементов(P) массива. Получается, что K=(TL/P)*N. Т.е. для того чтобы К был меньше чем log(N+M) нужно чтобы подавляющее большинство элементов из flag были false... ну если как-то возможно реализовать эти условия, то можно применить этот метод. Также не стоит забывать, что у варианта с сортировкой время будет всегда близко к NlogN, т.к. пока мы всё не отсортировали мы не можем начать искать, а во варианте с хешем, с шансами при первом же срабатывании условия flags будет найдено совпадение и поиск будет завершён.
     
  10. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    100gold
    какая ужасная программа! даже наукоподобная текстовка не компенсирует. незачет.
     
  11. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    100gold Общий смысл #9 понятен, спс...

    qqwe Буду гуглить, в вики наверняка есть...
     
  12. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    А не выгоднее ли сортировать массивы по-отдельности, а уже потом прямо по отсортированным однопроходно одновременно пробегаться?

    ИМХО, N*log(N) + M*log(M) меньше, чем (N+M)*log(N+M).

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

    i,i=0;
    while(i<N && j<M)
    {
    if(A>B[j])j++;
    else if(A<B[j])i++;
    else найдено
    }
    не найдено
     
  13. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    Хотя да, с хэшем явно будет быстрее.