재귀 (6) - 파일 탐색 (File Finding)

알고리즘

2020. 2. 4. 03:35

1. 알고리즘 개요

RFF(Recursive File Finding)은 알고리즘이라기 보다는 파일을 탐색하는 방법이라고 생각하면 더 쉽다. WINDOWS나 LINUX 등의 현대 운영체제는 모두 파일과 폴더의 구조를 가지고있다. 때문에 루트 디렉토리 (C:/)부터 여러개의 파일과 서브디렉토리를 가지고 각 서브디렉토리는 마찬가지로 여러개의 파일과 그들의 서브디렉토리를 가지고 있다. 이러한 구조를 탐색하기 위해 재귀함수를 사용할 수 있다. 근본적으로 서브디렉토리의 탐색과 루트디렉토리의 탐색에서 하는 역할이 동일하기 때문에 자기자신을 재호출하면 되기 때문이다.

 

[그림] Github 레포지토리 언어비율

 

이번에는 재귀함수를 이용해 소스코드 디렉토리를 탐색하고 디렉토리에 어떤 프로그래밍 언어가 많이 있는지 계산하는 애플리케이션을 개발한다. Github에서 각 레포지토리의 언어 비율을 보여주는 기능과 유사하게 생각하면 된다. 

 

2. 소스코드

작성자의 Github 레포지토리 중 TIL이라는 레포지토리의 언어비율을 알아본다. C++와 Python, Java 세가지 언어에 한해서만 조사하고 알고리즘, 머신러닝, 프로그래밍언어, 객체지향 패키지에 한해서만 조사하며, Python의 경우 실제 소스코드가 아닌 파일들은 전부 제거하였다. 구현은 Python을 사용하였다.

 

import os

root = "C:/Users/User/Github/TIL/"

def ratio_langs(dir):
    rff('c++', dir, cpp)
    rff('.py', dir, python)
    rff('.java', dir, java)

    return cpp, python, java


def rff(language, dir, list):
    root_listdir = os.listdir(dir)
    for file_name in root_listdir:
        if language in file_name:
            list.append(file_name)
        else:
            try:
                full_name = os.path.join(dir, file_name)
                rff(language, full_name, list)
                # Recurssion Call !
            except:
                pass


if __name__ == '__main__':
    cpp, python, java = [], [], []

    ratio_langs(dir=root + 'algo')
    ratio_langs(dir=root + 'ml')
    ratio_langs(dir=root + 'lang')
    ratio_langs(dir=root + 'oop')

    python = [file for file in python if '.pyc' not in file and
              '.pyd' not in file and '__init__' not in file]

    total = len(cpp) + len(python) + len(java)
    cpp = round(len(cpp) * 100 / total, 3)
    python = round(len(python) * 100 / total, 3)
    java = round(len(java) * 100 / total, 3)

    print('cpp : {}%'.format(cpp))
    print('python : {}%'.format(python))
    print('java : {}%'.format(java))
    
    """
    result : 
    
    cpp : 39.286%
    python : 38.095%
    java : 22.619%
    """

 

여기에서 주목해야할 것은 rff 함수이다. rff함수는 첫번째로 for loop를 이용하여 전체 파일/디렉토리 리스트를 탐색하고 이 중에 서브디렉토리가 있다면 서브디렉토리도 동일한 방식으로 탐색을 수행한다. 루트 디렉토리를 탐색하는 과정과 서브 디렉토리를 탐색하는 과정이 동일하기 때문에 탐색시에 재귀함수를 이용할 수 있다. 결과적으로 전체 파일을 탐색하여 각 언어 파일의 수를 모두 합해 각 언어가 어느정도 비중을 가지고 있는지 볼 수 있다.

 

모든 소스코드는 Github에서 확인할 수 있습니다.

 

gusdnd852/TIL

Source code collections of my blog 📝. Contribute to gusdnd852/TIL development by creating an account on GitHub.

github.com

 

3. Reference