๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm/ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] [3์ฐจ] ํŒŒ์ผ๋ช… ์ •๋ ฌ (Python)

1. ๋ฌธ์ œ ์„ค๋ช…

๋ฌธ์ œ ๋งํฌ

  • ์ž…๋ ฅ : ํŒŒ์ผ์ด๋ฆ„๋“ค
  • ์ถœ๋ ฅ : ๋ฌธ์ž๋ถ€๋ถ„, ์ˆซ์ž๋ถ€๋ถ„, ๋‚จ์€ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ์ •๋ ฌ๊ธฐ์ค€์— ๋งž๊ฒŒ ์ •๋ ฌ๋œ ํŒŒ์ผ๋ช… ์ถœ๋ ฅ

2. ์ฝ”๋“œ

solution1.py

from functools import cmp_to_key

def compare(s1,s2):
    head1, number1, tail1 = s1[0], s1[1], s1[2]
    head2, number2, tail2 = s2[0], s2[1], s2[2]

    head1, head2 = head1.upper(), head2.upper() #์•Œ๋ฐ”๋ฒณ ๊ตฌ๋ถ„ ์—†์œผ๋‹ˆ๊นŒ
    number1, number2 = int(number1), int(number2) #๋น„๊ต๋ฅผ ์œ„ํ•ด intํ™”

    if head1 != head2:
        return -1 if head1 < head2 else 1 #๋งŒ์•ฝ head1์ด head2๋ณด๋‹ค ์ž‘์œผ๋ฉด ๊ตํ™˜(-1)
    else: #head1 == head2
        return number1 - number2 if number1 != number2 else 1 #์ˆซ์ž๊ฐ€ ์„œ๋กœ ๊ฐ™์ง€ ์•Š์„ ๋•Œ๋งŒ ๋นผ๊ธฐ(๋‘˜์ด ๊ฐ™์„ ๋•Œ(๋‘˜์„ ์„œ๋กœ ๋นผ๋ฉด 0์ด๋‹ˆ๊นŒ) ๊ตํ™˜์ด ๋˜์–ด๋ฒ„๋ฆผ์„ ๋ฐฉ์ง€)

def split_fname(filename):
    HEAD = ""
    NUMBER = ""
    TAIL = ""
    i = 0
    while not filename[i].isnumeric():
        i+=1
    HEAD = filename[:i]

    j = i
    while filename[j].isnumeric():
        j+=1
        if j == len(filename): #TAIL์ด ์—†๋Š” ๊ฒฝ์šฐ
            NUMBER = filename[i:j]
            return [HEAD, NUMBER, '']

    NUMBER = filename[i:j]
    TAIL = filename[j:]

    return [HEAD, NUMBER,TAIL]


def solution(files):
    answer = []
    filenames  = []
    for file in files: #ํŒŒ์ผ๋ช… ํ•˜๋‚˜์”ฉ ์กฐํšŒ
        filenames.append(split_fname(file))

    filenames.sort(key=cmp_to_key(compare))

    for i, filename in enumerate(filenames):
        filenames[i] = ''.join(filename)
    return filenames
  • from functools import cmp_to_key๋กœ ์„ ์–ธ
  • functools.cmp_to_key(func) ํ•จ์ˆ˜๋Š” sorted์™€ ๊ฐ™์€ ์ •๋ ฌ ํ•จ์ˆ˜์˜ key ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ•จ์ˆ˜(func)๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
  • ๋‹จ, func ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›์•„๋“ค์ด๊ณ , ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋“ค์„ ๋น„๊ตํ•˜์—ฌ, ์ž‘์œผ๋ฉด ์Œ์ˆ˜, ๊ฐ™์œผ๋ฉด 0, ํฌ๋ฉด ์–‘์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋น„๊ต ํ•จ์ˆ˜์ด์–ด์•ผ ํ•œ๋‹ค.
  • ์ •๋ ฌ์„ ํ•  ๋•Œ, cmp_to_key๋ฅผ ํ™œ์šฉํ•ด์•ผํ•œ๋‹ค.
    • from functools import cmp_to_key๋กœ ์„ ์–ธ
    • cmp_to_key์•ˆ์—๋Š” compare ํ•จ์ˆ˜๋ฅผ ๋„ฃ๋Š”๋‹ค.
    • compare ํ•จ์ˆ˜๋Š” ๋น„๊ตํ•ด์„œ ์•ž ์›์†Œ๊ฐ€ ๋” ์ž‘์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•ด์„œ ์„œ๋กœ ๊ตํ™˜(์œ„์น˜๋ฅผ ๋ฐ”๊ฟˆ)ํ•˜๊ฒŒํ•˜๊ณ ,์„œ๋กœ ๊ฐ™์œผ๋ฉด 0์„ ๋ฐ˜ํ™˜(๊ตํ™˜), ์•ž ์›์†Œ๊ฐ€ ๋” ํฌ๋ฉด 1์„ ๋ฐ˜ํ™˜(๊ตํ™˜ํ•˜์ง€์•Š์Œ)ํ•œ๋‹ค.
  • ์ฃผ์˜ 1) tail์ด ์—†๋Š” ๊ฒฝ์šฐ
    • tail์ด ์—†๋Š” ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค. ์•ˆํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์Œ
  • ์ฃผ์˜ 2) ํŒŒ์ผ๋ช… ์›์ƒ๋ณต๊ท€
    • ''.join(filename) ๋กœ ๋‚˜๋ˆ„์–ด๋†“์€ ํŒŒ์ผ๋ช…๋ฆฌ์ŠคํŠธ๋ฅผ stringํ˜•ํƒœ๋กœ ๋ฐ”๊ฟ”์ฃผ์ž

solution2.py

def solution(files):
    tmp = []
    head, number, tail = '', '', ''

    for file in files:
        for i in range(len(file)):
            if file[i].isdigit():     # ์ˆซ์ž๊ฐ€ ๋‚˜์˜ค๋ฉด ๊ทธ ์ด์ „์€ ๋ฌด์กฐ๊ฑด HEAD, ์ดํ›„๋Š” NUMBER, TAIL๋กœ ๋‹ค์‹œ ๊ตฌ๋ถ„
                head = file[:i]
                number = file[i:]

                for j in range(len(number)):    # NUMBER์™€ TAIL ๊ตฌ๋ถ„ (์ˆซ์ž ์•ˆ๋‚˜์˜ค๋ฉด TAIL)
                    if not number[j].isdigit():
                        tail = number[j:]
                        number = number[:j]
                        break

                tmp.append([head, number, tail])
                head, number, tail = '', '', ''
                break

    tmp = sorted(tmp, key=lambda x:(x[0].lower(), int(x[1])))

    return [''.join(i) for i in tmp]
  • for๋ฌธ๊ณผ break๋ฌธ ์‚ฌ์šฉ์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ํ‘ผ ํ’€์ด์ด๋‹ค.
  • ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๋‹ค.

solution3.py

import re
import re
def solution(files):
    temp = [re.split(r"([0-9]+)", file) for file in files]
    sort = sorted(temp, key = lambda x: (x[0].lower(), int(x[1])))

    return [''.join(s) for s in sort]
  • ์ •๊ทœํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ file์˜ ์ˆซ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ split
  • r'(\d+)' ๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅ

4. ์ฐธ๊ณ 

https://www.youtube.com/watch?v=IcNPpsG8i2s
https://wikidocs.net/109303
https://velog.io/@sem/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LEVEL2-%ED%8C%8C%EC%9D%BC%EB%AA%85-%EC%A0%95%EB%A0%AC-Python