??? Быстрый алгоритм поиска максимального номера в расширении файла

Тема в разделе "WASM.A&O", создана пользователем Alice1144, 11 мар 2009.

  1. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    Есть некая папка с кучей файлов. В расширении файла пишется номер п/п (например файл: вв5вввв.345). Подскажите быстрый алгоритм поиска максимального номера (на С/С++). файлы считаются с 000, отдельные номера могут отсутствовать, сортировка по дате файлов не подходит.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Ndec = 10 ^ I - 1, I - число разрядов.
     
  3. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Если номера файлов идут по порядку используй метод половинного деления

    1. n=500, m=250
    2. Проверяем существует ли файл n, если да n=n+m, m=m/2, если нет - n=n-m, m=m/2
    3. Повторяем шаг 2 пока m>0
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    dir /b > list.txt
    и там ищи
     
  5. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Ну тогда вот примерно так
    Код (Text):
    1. var
    2. finddata: WIN32_FIND_DATA;
    3. i:           byte;
    4. s:          string;
    5.  
    6. begin
    7.  
    8. i:=9;
    9. s:='*.';
    10. while(FindFirstFile(s+char(i+48)+'*',finddata)=INVALID_HANDLE_VALUE) do
    11.     i:=i-1;
    12.  
    13. i:=9;
    14. s:=s+pchar(dword(cFileName)+strlen(finddata.cFileName)-3)^;
    15. while(FindFirstFile(s+char(i+48)+'*',finddata)=INVALID_HANDLE_VALUE) do
    16.     i:=i-1;
    17.  
    18. i:=9;
    19. s:=s+pchar(dword(cFileName)+strlen(finddata.cFileName)-2)^;
    20. while(FindFirstFile(s+char(i+48),finddata)=INVALID_HANDLE_VALUE) do
    21.     i:=i-1;
    22.  
    23. s:=s+pchar(dword(cFileName)+strlen(finddata.cFileName)-1)^;
     
  6. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Быстрее всего получить список файлов с помощью NtQueryDirectoryObject
     
  7. agrischuk

    agrischuk New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2009
    Сообщения:
    47
    Получаешь список файлов, начинаешь сравнивать текущий максимальный со следующим.
    Сложность O(n), быстрее не бывает :)
    Что не понятно?
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    murder
    Весьма примерно ;)
    По мелочи понятно: нужно добавить в while ограничение на i >= 0 (иначе если вообще нет файлов с цифрами в расширении, то первый цикл будет крутиться до посинения), ну и ес-но FindClose не забыть добавить.

    По существу: после первого цикла надо бы проверить соответствие расширения цифровому шаблону и второй цикл крутить не от 9 вниз, а от второй цифры найденного файла вверх, т.к. мы ищем макс.номер. Ну и третий цикл - если на втором ничего не нашли, то выходим, если нашли, то от найденной цифры - вверх

    agrischuk
    Найти макс.число в списке - не проблема, т.к. тут основное время уйдет на получение списка файлов. Поэтому основной вопрос - что быстрее, получить сразу весь список или же хитрить с масками FindFirst как murder. Если файлов мало, то скорее всего быстрее будет получить весь список (т.к. на FindFirst и FindClose требуется доп.время), если же - много, то возможно хитрости с масками окажутся быстрее.
     
  9. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Также быстро получить список файлов в директории можно с помощью GetFileInformationByHandleEx
    При этом не происходит перебора всех файлов, а сразу читается содержимое директории.
     
  10. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Что-то мне подсказывает, что поиск среди имён файлов даже банальнейшим перебором всё равно будет быстрее, чем собственно чтение списка всех файлов в директории с предварительным выделением под него памяти.
     
  11. agrischuk

    agrischuk New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2009
    Сообщения:
    47
    А как по твоему эти маски проверяются? Они же не с неба падают, это значит ОС делает за тебя эту работу. Причем можно показать что в общем случае оно будет медленее нежели самому сделать этот перебор, так как каждый раз когда делается запрос по маске, проверяется весь список. Никак FindFirst/Next не будет быстрее.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    agrischuk
    А ты как предлагаешь "получить список файлов" ? Через шелл-апи или последовательны перебором через те же FindFirst\FindNext или NtQueryDirectoryObject ? Если перебором, то нужно учитывать накладные расходы на многократные переходы из юзермода в кернел, плюс копирование кучи ненужных FIND_DATA. Поэтому при большом числе файлов может оказаться, что пробежаться несколько раз по списку внутри ОС окажется быстрее чем "выдавать в час по чайной ложке" для формирования полного списка на стороне юзера
     
  13. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    leo
    Вопрос в том, каким должно быть количество файлов, чтобы получить выигрыш. Здесь идёт речь максимум о 1000 файлах.
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    murder
    Да может и вообще никакого выигрыша не будет - я же не утверждаю, а лишь рассуждаю ;)
    А именно уточняю, что под сложностью O(n) может скрываться x*N, где x зависит от конкретной реализации
     
  15. agrischuk

    agrischuk New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2009
    Сообщения:
    47
    NtQueryDirectoryFile возвращает много файлов. Кстати почему ты считаешь что каждый раз FindNextFile будет обращаться в kernel? Сие очень не тривиально, и если оно действительно так делает - еще один камень в огород win api.
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    agrischuk
    Упс, и в самом деле FindFirst вызывает NtQueryDirectoryFile и получает сразу весь список файлов, а FindNext только копирует данные из этого списка в буфер (ес-но в юзермоде). Значит я не прав, посыпаю голову пеплом и бегу поджавши хвост ;)