Подходит ли мой анализ времени и пространства для этого алгоритма?
def find_files(suffix, path):
if suffix == '':
return []
# Base condition
if len(os.listdir(path)) == 0:
return []
path_elements = os.listdir(path)
path_files = [file for file in path_elements if ('.' + suffix) in file]
path_folders = [folder for folder in path_elements if '.' not in folder]
for folder in path_folders:
path_files.extend(find_files(suffix=suffix, path=path + '/' + folder))
return path_files
# Tests
path_base = os.getcwd() + '/testdir'
print(find_files(suffix='c', path=path_base))
Объяснение: Рекурсия файла
Требование:
Цель состоит в том, чтобы написать код для поиска всех файлов в каталоге (и во всех каталогах ниже него), которые заканчиваются на ".c"
Резюме:
Чтобы реализовать это, я использовал функцию find_files
, которая будет принимать suffix
(расширение файла) и path
(путь к каталогу, в котором нам нужно искать). В этой функции я рекурсивно ищу файл с заданным расширением в родительском каталоге и во всех его подкаталогах. Я сохраняю все эти файлы с заданным суффиксом в списке и возвращаю его.
Сложность времени и пространства:
Сложность времени:
os.listdir (путь) выведет список всех файлов и папок по заданному пути. Поскольку он должен перебирать каждый элемент, чтобы предоставить список, это требует линейной временной сложности. Пусть e
будет длиной path_elements => O(len(path_elements))
=> O(e)
path_elements = os.listdir(path)
- Строка ниже обнаружит все файлы по заданному пути, проверив, есть ли
.c
в имени файла. Еслиs
- это длина строки (имя файла / папки), то требуетсяO(s)
времени, чтобы найти файл с заданным расширением. Следовательно, дляf
количества файлов требуетсяO(f*s)
времени. Для практических целей, подобных этому, будет справедливо предположить, что имена файлов НЕ бесконечно длинные. Следовательно, мы можем принятьs
как константу =>O(f * 1)
=>O(f)
.
path_files = [file for file in path_elements if ('.' + suffix) in file]
- Точно так же переход по
g
каталогам займет линейное время =>O(g)
path_folders = [folder for folder in path_elements if '.' not in folder]
Вышеупомянутые 3 шага потребуют => O(e + f + g)
=> O(e)
. Поскольку e
(len(path_elements)
) является доминирующим термином, поскольку представляет собой комбинацию path_files
и path_folders
- Для рекурсии, если
k
- это количество каталогов (branches
) на каждом уровне вdepth
, тогда рекурсия займетO(brancher^depth)
=>O(k^depth)
. Но для каждого рекурсивного вызова выполняется более трех шагов. Следовательно, общая временная сложность составляетO((k^depth) * e
.
Сложность пространства:
Входное пространство
- suffix -
O(1)
- путь -
O(1)
- path_elements + path_files + path_folders =>
O(e + f + g)
=>O(e)
- suffix -
Вспомогательное пространство
Рекурсия использует так называемый «стек вызовов». Когда функция вызывает себя, эта функция идет поверх стека.
- In this algorithm, the recursive function is exhausted only if it has traversed every directory. In other words, when it has reached the
depth
. ThereforeO(depth)
space is required in the call stack.
- In this algorithm, the recursive function is exhausted only if it has traversed every directory. In other words, when it has reached the
Общая сложность пространства => Входное пространство + Вспомогательное пространство =>
O(e + depth)
.
? - person Jim Mischel   schedule 16.04.2020('.' + suffix) in file
. Это перехватит .com, .cfg, my.cool.file и все остальное, что содержит .c. - person Jim Mischel   schedule 16.04.2020.
, а в именах файлов есть только один.
. Мне нужна ваша помощь, чтобы подтвердить мой анализ времени / пространства. Код отлично работает для данного варианта использования. В основном это структура папок:./testdir ./testdir/subdir1 ./testdir/subdir1/a.c ./testdir/subdir1/a.h ./testdir/subdir2 ./testdir/subdir2/.gitkeep ./testdir/subdir3 ./testdir/subdir3/subsubdir1 ./testdir/subdir3/subsubdir1/b.c ./testdir/subdir3/subsubdir1/b.h ./testdir/subdir4 ./testdir/subdir4/.gitkeep ./testdir/t1.c ./testdir/t1.h
- person Suhas Srivats Subburathinam   schedule 16.04.2020O(path_elements)
, гдеpath_elements
- общее количество элементов, возвращаемых всеми вызовамиos.listdir
. Чтобы получить 100 файлов из 10 разных папок, требуется немного больше, чем только из двух, но это зависит от константы. Однако фактическое время будет несколько другим. - person Jim Mischel   schedule 17.04.2020