Algorithm/LeetCode

[LeetCode][C++/Python] 937번: Reorder Data in Log Files (258)

샤아이인 2022. 12. 26.

 

생각의 흐름

사실 크게 생각할 문제라기 보다는, 정렬 조건을 어떻게 잘 적용시키는지가 중요한 문제이다.

 

C++, Python 둘다 람다를 활용하여 간편하게 정렬 조건을 전달해줄 수 있다. 이를 활용해보자!

 

나의 코드

1. C++

using namespace std;

class Solution {
public:

    vector<string> reorderLogFiles(vector<string>& logs) {
        vector<string> digits;
        vector<string> letters;

        for (auto log : logs) {
            const vector<string> &results = split(log, " ");

            if(isdigit(results[1][0])) {
                digits.push_back(log);
            } else {
                letters.push_back(log);
            }
        }

        auto compare = [] (auto a, auto b) {
            int i = a.find_first_of(' ');
            int j = b.find_first_of(' ');
            if(a.substr(i, a.size() - i) != b.substr(j, b.size() - j)) {
                return a.substr(i, a.size() - i) < b.substr(j, b.size() - j);
            }
            return a.substr(0, i) < b.substr(0, j);
        };
        sort(letters.begin(), letters.end(), compare);

        letters.insert(letters.end(), digits.begin(), digits.end());
        return letters;
    }

    vector<string> split(string input, string delimiter) {
        vector<string> ret;
        long long pos = 0;
        string token = "";

        while ((pos = input.find(delimiter)) != string::npos) {
            token = input.substr(0, pos);
            ret.push_back(token);
            input.erase(0, pos + delimiter.length());
        }

        ret.push_back(input);
        return ret;
    }
};

compare를 람다식을 활용하여 만든 후, sort에 인자로 전달해주었다!

사실상 split만 직접 구현한점은 제외하면, Python과 동일한 코드라 생각된다.

 

나도 처음 사용해보는 함수가 있어서 정리해보았다.

  • find_first_of : 전달된 문자들 중 첫 번째로 일치하는 것의 위치를 찾는다.
  • find_last_of : 전달된 문자들 중 가장 마지막에 나타나는 문자의 위치를 찾는다.

 

find_firt_of에 대한 설명은 다음 글을 살펴보자.

https://modoocode.com/249

 

C++ 레퍼런스 - string 의 find_first_of 함수

 

modoocode.com

또한 2개의 vector를 합치기 위해서 C++의 insert 구문을 사용하였다.

 

코드를 좀더 줄이면 다음과 같은 코드도 가능하다.

using namespace std;

class Solution {
public:

    vector<string> reorderLogFiles(vector<string> &logs) {
        auto alpha_first = [](auto &log) -> bool { return isalpha(log.back()); };
        auto it = stable_partition(logs.begin(), logs.end(), alpha_first);

        auto compare = [](auto a, auto b) {
            int i = a.find_first_of(' ');
            int j = b.find_first_of(' ');
            if (a.substr(i, a.size() - i) != b.substr(j, b.size() - j)) {
                return a.substr(i, a.size() - i) < b.substr(j, b.size() - j);
            }
            return a.substr(0, i) < b.substr(0, j);
        };
        sort(logs.begin(), it, compare);

        return logs;
    }
};

stable_partition을 통해 알파벳 부분만 앞쪽에 정렬시키는 방법이다.

반환되는 iterator는 두번째 그룹의 첫번째 원소에 해당된다.

 

sort를 할때 logs.begin()부터 it전까지로 명시하면, 이는 알파벳 그룹만을 정렬하게 된다.

 

2. Python

class Solution:
    def reorderLogFiles(self, logs: List[str]) -> List[str]:
        let = []
        dig = []

        for log in logs:
            results = log.split(" ")
            if results[1].isdigit():
                dig.append(log)
            elif results[1].isalpha():
                let.append(log)

        let.sort(key=lambda x: (x.split()[1:], x.split()[0]))
        return let + dig

파이썬은 너무나 간단하게 코드가 끝나버린다 ㅋㅋㅋㅋㅋ

댓글