02_reorder_data_in_log_files

Numeric_combo·2024년 6월 20일

알고리즘-공부

목록 보기
3/6

제시문:

You are given an array of logs. Each log is a space-delimited string of words, where the first word is the identifier.

There are two types of logs:

  • Letter-logs: All words (except the identifier) consist of lowercase English letters.
  • Digit-logs: All words (except the identifier) consist of digits.

Reorder these logs so that:

  1. The letter-logs come before all digit-logs.
  2. The letter-logs are sorted lexicographically by their contents. If their contents are the same, then sort them lexicographically by their identifiers.
  3. The digit-logs maintain their relative ordering.
    Return the final order of the logs.

솔루션

class Solution:
    def reorderLogFiles(self, logs: List[str]) -> List[str]:
        # seperate letter logs and digit logs
        letters, digits = [], []
        for log in logs:
            # check whether the second substring of an element is digit or not
            if log.split()[1].isdigit(): 
                digits.append(log)
            else:
                letters.append(log)
        
        # use lambda expression to sort letters 
        # (we don't care digits as they are sorted relatively)
        letters.sort(key=lambda x: (x.split()[1:], x.split()[0])) # remember [1:]
        return letters + digits # notice this adding pattern   

어떻게 코드를 짤지에 대한 논리적 흐름은 잘 맞췄는데 이에 대응되는 함수들을 떠올리지 못해 풀지 못했었다 :( 복습과 평소 코딩 이것저것 해봄의 중요성을 느낌..

알아둘 것들은 다음과 같다.

split()
주어진 문자열을 띄어쓰기(=speace-delimited)를 기준으로 분리한다. 위 솔루션의 경우, logs라는 리스트에서 각 원소(=log)를 split()을 이용해 띄어쓰기를 기준으로 쪼갠 후, 여기서 index == 1인 경우를 선택한 뒤 이것이 디짓인지 아닌지 판단한다. 디짓이라면 digits이란 리스트에 추가, 아니면 letters에 추가한다.

isdigit()
함수 제곧내. 물론 isalpha()도 있다.

lambda 매개변수 : 표현식
맨날 봤는데 까먹는 이눔의 람다...위 코드에서 람다는 다음과 같이 작동한다. 먼저 람다가 사용된 것만 떼어놓고 보자.

letters.sort(key=lambda x: (x.split()[1:], x.split()[0]))
  1. sort() 함수에서 key 매개변수는 정렬을 하기 위해 각 원소를 비교하기 이전에 각 리스트들의 원소들에 대한 함수를 무엇으로 할지 구체화한다.
  2. lambda x 이하는 주어진 리스트 x의 각 원소들을 쪼갠 뒤 튜플((x, y) 꼴로 생긴 걸 주목하자)로 리턴한다.
  3. x.split()[1:]는 리스트 x의 원소들 중 index == 1인 것부터 시작해 그 뒤 나머지 원소들을 띄어쓰기를 기준으로 접근한다.
    3-1. 예컨대 ''2 A'',이라면 '['A']'로 접근할 것이고,
    3-2. ''2 A B''라면 '['A', 'B']'로 접근할 것이다 ([1:]니깐!)
  4. x.split()[1:], x.split()[0]을 수행한 후 이 람다 함수는 2에서는 말한 것처럼 이 모양꼴 그대로 튜플로 리턴할 것이므로, 예컨대 ''2 A''라면 '(['A'], '2')'로 리턴할 것이다.
  5. 이렇게 출력된 튜플들은 다시 sort()를 통해 정렬될 것이고, 이 때 정렬함수는 튜플의 index == 0인 원소를 기준(이 경우 알파벳 또는 lexicographically순)으로 정렬될 것이다.

return digits + letters
두 개의 리스트를 더할 때 따로 정렬없이 그대로 더해진다. 예컨대 digts = [1], letters =[a]라면 위 리턴 함수는 [1, a]를 출력할 것이고, 반대로 적혀있다면 [a, 1]로 출력될 것이다.

profile
덕질기록용

0개의 댓글