нужен эффективный алгоритм

Тема в разделе "WASM.ASSEMBLER", создана пользователем Vic, 24 фев 2009.

  1. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    День добрый, всем,
    Нужен совет, если кто сталкивался....
    Задача вполне тривиальная - поиск подстроки в стоке, Алгоритмы Бойера Мура, Карпа Рабина, построение автоматов - ссылки листал, другое дело в их описании говорится об эффективности на больших строках.

    У меня же условия такие: массив строк в памяти - ну скажем каждая не длиннее 10 символом (длинна самого массива порядка 20 элементов)... так же в другой области в памяти, находится строка которую надо проверить есть ли такая же в массиве (строка тоже не длиннее 10 символом)

    Реализуется на асме, но нужно сделать как можно эффективнее.

    Может использовать, так сказать, сравнение "в лоб", то есть посимвольно сравнивать?? или есть более быстрый способ??
     
  2. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Если искать именно подстроку (т.е. при строке "soft" и наличии в массиве "microsoft" считать это совпадением) - кроме как в лоб и посимвольно, для коротких строк, эффективнее не сделать. Можно сравнивать по двойному слову (это выглядит несколько быстрее, чем по 1 символу), сдвигаясь в массиве на 1 байт, но эффективность будет страдать (чтение двойного слова с некратного 4 адреса даст некоторое падение производительности - не факт, что будет заметный выйгрыш).

    Если есть дополнительные ограничения:
    - не подстрока, а точное совпадение строк или совпадения только с началом строки,
    - максимальный размер строк - кратный 4 байтам,
    - максимальный размер постоянен для всех элементов массива и образца,
    - все строки с длиной менее максимальной гарантированно дополнены нулями до конца
    ...
    то можно подумать о более эффективных и быстрых вариантах, чем посимвольное сравнение.
     
  3. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    требуется поиск полного совпадения введенной строки слову из массива... (задача сама по себе простая, но нужно реализовать как можно эффективнее) - других ограничений вроде нет, ну разве что про размер написал выше...

    Что посоветуете??
     
  4. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    Тут кстати подумал, и вроде с помощью хешей может не плохо получиться...
     
  5. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    если кто реализовывал что нибудь подобное подскажите. потому что сейчас опять обдумал и получается что при использовании хэшей, больше времени уйдет на работу с большими числами...
     
  6. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Идею про хеши в студию! Какой хеш и с каким вы сравнивать собираетесь?
     
  7. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    Если Вы про хеш функцию, пока не знаю. Гугл подсказывает:
    А по поводу сути, то подумал может, вычислить хеш от каждой из строк в массиве (тут можно даже заменить сами строки массива на их хеши, потому что строки будут неизменны), и по ходу выполнения программы считать хеш от введенного слова и уже сравнивать с содержимым массива.
     
  8. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    но хеши могут повторяться, если не сохранить оригиналы строк, можно нарваться на ошибку. тестируя хеш функцию не забудьте убедиться, что все они оригинальны (хеши оригинальны для каждой строки), хотя это не исключит возможность ошибки. где гарантия, что хеш введенной строки не совпадет с хешем из таблицы. тут важно найти совпадения по хешу и потом сравнить строки, тогда ошибки не будет.
     
  9. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Советую глянуть в сторону алгоритма Ахо-Корасик (конечный автомат).
    Ну если кол-во элементов в массиве ограниченно 20-тью, то наверное не стоит на асме реализовывать конечные автоматы (можно и перебором, если строка не очень длинная =).
     
  10. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    max7C4
    Да про то, что повторяться могут в курсе (спасибо что все таки упомянули, потому что и правда нужно копию строки хранить)

    Только вот тут опять наболевший вопрос насколько это эффективно (в контексте условий задачи). Ведь числа получаются большие и использовать придется MMX + операции умножения, оно того стоит ???

    T800
    Спасибо, но по поводу автоматов в данном случае кажется все таки цель не оправдывает средства
     
  11. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Vic
    Трудности при построении дерева Бора. А сам поиск это элементарный цикл из 9-15 интрукций (скорость чумовая =).
     
  12. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    T800
    поясни пожалуйста, про поиск и элементарный цикл, - это ты по поводу чего?? реализации ДКА? или про дерево Бора?
     
  13. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Код (Text):
    1. mov ebx, buffer
    2. mov eax, last
    3. mov ecx, length
    4. not eax
    5. lp0:
    6.   xor edx, edx
    7.   mov dl, al
    8.   xor dl, [ebx]
    9.   inc ebx
    10. ;========эта часть==========
    11.   mov edi, 8
    12.   lp1:
    13.     shr edx, 1
    14.     jnc @f
    15.       xor edx, 0xEDB88320
    16.     @@:
    17.   dec edi
    18.   jnz lp1
    19. ;========эта часть==========
    20.   shr eax, 8
    21.   xor eax, edx
    22. loop lp0
    23. not eax
    CRC32 для таких строк вполне подойдет, повторяться будет достаточно редко, но будет и работает достаточно быстро (и не придется использовать mmx, сравнивать придется всего-то 4-байтные величины)
    P.S. Вот это часть всегда выдает одни и теже значения. Если не жалко 1 Кб памяти можете составить таблицу и заменить эту часть на
    Код (Text):
    1. mov edx, [esi+edx*4]
    соответственно в esi надо будет в начале
    Код (Text):
    1. mov esi, CRC32Table
     
  14. Vic

    Vic New Member

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    75
    max7C4
    Спасибо большое, с алгоритмом пока не разбирался, ближе к вечеру отпишусь что и как. Пока только один вопрос
    - то есть тем не менее придется при получении совпадения CRC32 сравнивать уже побайтно??
     
  15. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    желательно
    все таки CRC кодов всего 4294967296 (2^32) а вариантов строк из 10 байт 2^80