06_정렬_파일이름
# ref)
문제 : https://programmers.co.kr/learn/courses/30/lessons/17686?language=python3
정규식 참고 : https://painted-starfish-9d5.notion.site/1582b2da920780e3a228e91a1592c5fc
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
참고) 정규식 | Notion
정규식은 텍스트 문자열을 어떠한 패턴으로 파악하여 식별하는데 사용이 된다. → 내가 지정한 규칙에 해당하는지, 해당하지 않는지에 대해서 알려주게 된다.
painted-starfish-9d5.notion.site
# 참고 : 정규식!!!! ==> 문자열에 대한 패턴/ 규칙 표현!!!!!
---> gpt를 이용하시면 편하지 않을까...
: 카카오 계열사의 특징 중 하나 종종 정규식
: 일반적인 부분에서는 자주 나오지는 않음;;;
//리스트랑 dict를 모두 연습하자
문제 상황을 체크!!!
기존의 정렬 방식 : 글자별로 코드값을 기준으로 하나씩 정렬!!!!
img10.png, img2.png
==> img2.png, img10.png( 숫자크기가 대소 반영!!!)
파일명 : 영문대/소, 숫자, 공백, 마침표, 빼기기호
최대 길이가 100글자
: 제약조건 ==> 시작은 영문자(대/소)
==> 숫자는 무조건 1개 이상!!!
파일명의 구성 : 3가지 파트로 구성
head : 처음부터~~~ 처음숫자가 나타나기 전까지 부분!!!!!
number : 처음 숫자 덩어리파트 (+++ 0010 제로 패딩!!!!)
tail : 그 외.....
위의 3가지 파트를 기준으로 정렬!!!
정렬기준1) head 파트 & 사전순(오름차순)
단, 대/소문자 구별X ==> 통일이 필요할 것!!(대 or 소)
정렬기준2) number파트 & 숫자크기(오름차순)
단, zero padding 앞 처리 --> 00010 : 10
정렬기준3) 원본의 순서를 유지해주세요!!!
---> tail부분은 정렬에 사용하지 않네;;;;
---> tail은 굳이 처리를 안 해도 되지않을까;;;;
단,,,,,원본의 순서!!!!!!!
주관적인 결론!!!)
정렬에 대한 필요한 정보 (head, number, 원본순서)
+ 최종 출력 : 원본 파일명
==> ( 원본파일명, head, number, 원본순서)
샘플 케이스 분석
# 예제1
입력 :["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]
==> 출력: ["img1.png", "IMG01.GIF", "img02.png", "img2.JPG", "img10.png", "img12.png"]
1) 필요한 정보를 추출 : head, number, 원본순서
"img12.png" : img, 12, 0 (6)
"img10.png" : img, 10, 1 (5)
"img02.png" : img, 02, 2 (3)
"img1.png" : img, 1, 3 (1)
"IMG01.GIF" : IMG, 01, 4 (2)
"img2.JPG" : img, 2, 5 (4)
==> 출력 양식 : 내가 정리한 정보 스타일X
입력으로 받은 원본 파일명으로 그대로 출력!
==> 리스트로 구현을 할 것인가,,,dict로 할 것인가...선택!!!!!
# 예제2
입력: ["F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"]
-->출력: ["A-10 Thunderbolt II", "B-50 Superfortress", "F-5 Freedom Fighter", "F-14 Tomcat"]
F-5 Freedom Fighter : (F-, 5, 0) (3)
B-50 Superfortress : (B-, 50,1) (2)
A-10 Thunderbolt II : (A-, 10,2) (1)
F-14 Tomcat : (F-, 14, 3) (4)
정렬을 하기 위한 필요한 정보들을 추출하는 과정에서.. 규칙!!!!
==> 기준 : 파일명 속에서 처음 나타나는 숫자!!!!( 숫자 1~5글자,0~9, 제로패딩)
기준앞 : head
기준 : number
==> 문자열에 대한 규칙화 문법 : 정규식!!!!
파이썬의 잡다한 문자열에 대한 기능(메서드) / 리스트 //정규식과 메서드 공부하자!!
사전 지식 1) 정규식!!!!!
목적 : 문자열 내에서 내가 원하는 패턴을 찾는 룰(규칙!!!)
---> 일반적인 모든 언어들에 대해서 다 존재를 함!!!!
큰 틀에서는 거의 유사함!!!조금 언어별로 차이가 있는 구문이 있을 수 있음!!!
---> 파이썬 : re패키지 (코테 플랫폼 : 기본으로 사용할 수 있는 패키지!!!) //re 정규식 정리하기!!
import re
==> anaconda 패키지 버전에서도 기본으로 설치가 되는 패키지!!!
colab에서도 기본적으로 설치가 되어 있음!!!!
==> 필요하면, 불러오기만 하면 됨!!!!!!!
// https://proximal-stranger-fa0.notion.site/re-cd9966fe6c3b4756acf72df084910b51
re 정규표현식 | Notion
1. 정규 표현식 문법과 모듈 함수
proximal-stranger-fa0.notion.site
#정규식의 규칙으로 작성된 문자열 vs 쌩파이썬의 문자열!!!!
"hello. 100$" # -- 일반적인 문자열
r"hello. 100$" # -- 일반적인 문자열 앞에서 r
--> 일반 문자열이 아니라 정규식으로 작성된 문자열!!!!!
==> .()\[]*+ 기호들이 일반적인 특수문자 기호가 아니라....
정규식 패키지가 사전에 정의해놓은 규칙을 표현하는 문자!!!!!!!
#정규식 기본 틀
* vs + : 원하는 패턴0번 이상 vs 원하는 패턴1번 이상 ==> 출현 빈도
[문자들] : 여러개들 중에서 하나라도,,,,,==> [Pp]ython
. : 줄바꿈을 제외하고 뭐라도 1개 문자/공백
{n} : 패턴의 반복을 지정!!!!!
[0123456789] # 0~9까지 숫자 중 하나 체크!!!!
[0-9]
\d # 편하기는 하지만,,,,구체적으로 컨트롤을 할 수 없음!!!!
---> 하나만 알면 되지 않을까요???? No!!!!
예) 주민번호 XXXXXX - [1234]XXXXXX
XXXXXX - [1-4]XXXXXXX
# 정규식을 특정 패턴에 대해서 찾을 때 ===> findall
re.findall( 패턴-->규칙(정규식룰), 어디서)
temp ="SSdsdsdsdsd1w32fdfdfadfadf1343434****343sdasxdqrsf.fdfppdfdf134ff"
temp
ex) 찾을 규칙 : 숫자1개로 이루어진 것들을 다 찾아주세요!!!!
re.findall( r"\d", temp)
ex) 찾을 규칙 : 숫자1개 이상으로 연결된 것들은 다 찾아줘!!!
re.findall( r"\d+", temp)
re.findall( r"\d*", temp)
===> 꼭!!! 제대로 원하는 패턴이 잘 찾아지는제 테스트를 꼭 하세요!!!
re.findall( r"[0123456789]+",temp)
re.findall( r"[0-9]+",temp)
re.findall( r"[3-4]+",temp)
re.findall( r"[a-z]+",temp) # 소문자 1개 이상 연속된 패턴!!!!
re.findall( r"[A-Z]+",temp) # 대문자 1개 이상 연속된 패턴!!!!
[a-zA-Z] : 대소문자 다 가능!!!!
[A-z] : 대소문자 다 가능!!!!
==> [a-Z] : 에러가 발생을 하는 정규식!!!
re.findall( r"[A-Z]+",temp)
# 사전지식2) 숫자 앞에 붙은 0을 어찌처리할까요????
===> 정렬을 하기 위해서는 0이 제거된 숫자가 필요함!!!
"000023" ---> 숫자 23
[1-9]+ : 203 xXXXXXXX
int("00023")
str( int("00023"))
# 사전 지식 1&2적용 : temp문자열에서 한 번 처리를 해보죠!!!
temp ="SSdsdsdsdsd032fdf2dfa9dfadf134300434****00343sdasxdqrsf.fdfppdfdf1034ff"
temp
re.findall(r"\d+", temp)
re.findall(r"\d+", temp)[0] # --> number파트 추출!!!!!
[ 1,3,3,3,4,2,3,3,5].index(4)
"aasdsdsdsdsdsds".index("d")
temp.index(re.findall(r"\d+", temp)[0] ) //number 파트 구현
temp[:temp.index(re.findall(r"\d+", temp)[0] )] //number 파트 재활용
# ---> head파트....
# 사전지식3) 문자열 --> 정렬을 대소문자 동일하게 간주!!!!
===> 문자열에서 대소문자에 대한 일괄변환!!!!
"AAAssdsdFD".lower()
"AAAssdsdFD".upper()
방법1) 리스트를 사용해서 체크!!!!!
---> (head:소문자, number:숫자, 원본위치)
---> (head, numner, 원본위치, 원본파일명) [ 개인적으로 한 번 해보세요!!!]
방법2) dict 사용해서 체크!!!!!!!!!
--> k : 파일명(중복된 파일명이 없음!!!!!)
v : (h, n, idx)
# Try1) 리스트 --> (h, n, idx)
import re
def solution(files):
answer = []
##
# 0. 기본적인 세팅 : 정렬에 필요한 정보를 담을 변수 : 리스트
# --> (head : 소문자, number : 숫자, 원본위치)
my_files = [] # [(h,n,i), (h,n,i), ...]
# 1. 돌리는 큰 틀 : 입력의 files 리스트를 다 돌리면...
==> 원하는 정보를 추출, my_files에 담으면 됨!!
++ 원본위치 : 입력 파일리스트의 정수 인덱스
for idx, s in enumerate(files) :
# s 개별 파일명 --> h, n 정보 추출!!
# 1-1) 기준 : 가장 처음에 나타나는 숫자 덩어리 ==> 정규식!!
number = re.findall( r"\d+",s) # s:foo010bar020.zip --> [ "010", "020"]
# 이 중에서 가장 처음 나타난 숫자 덩어리 + 숫자화!!
real_number = int(numbers [0]) # "010" --> int --> 10
# ==> number 파트 정리 끝!
# 1-2) head 파트 추출 : 처음~~ 숫자파트 시작 전
head = s[:s.index(numbers[0])] # Foo
head = head.lower() # Foo --> foo
# 1-3) 필요한 정보를 모으자!!
# ["foo", 10, 0], ["img",3,1] ,...]
my_files.append([ head , real_number , idx ])
# --> 입력으로 받은 files들을 다 처리르 하면 됨!!
# 2) 문제에서 주어진 조건대로 정렬!!!
# + 일반적인 조건이 아니라 주어진 대로 내가 직접 작성!!
# .sort(), sorted() + key + lambda + (+/-)
# ==> 원본에 대한 파일명 : files에 아직 그대로 존재!!
my_files.sort( key = lambda x: (x[0], x[1], x[2]) )
# [["img",3,1], ["zmgoo", 10, 0],...]
# 3) 최종 제출 스타일로 정리!! --> 원본 파일명!!
# for j in my_files: # ["aaa", 10, 3]:
# answer.append(files[j[2]])
answer = [files[ j[2]] for j in my_files]
return answer
# Try2) Dict
==> my_files = {}
k : 중복이 없는 원본 파일명 --> 문제에서 중복 없다고 해서..
v : 정렬에 필요한 정보 (head, number, org_idx)
==> 정렬을 기준이 어디에?? --> 오로지 value에 존재!!
my_files.items(), my_files.values() etc...
import re
def solution(files):
answer = []
# 세팅
my_files = {} # k : 파일명, v : (h,n,idx)
#개별 파일들을 돌아가서
for idx, s in enumerate( files ):
p = re.findall(r"\d+", s) [0]
head = s[:s.index(p)].lower()
number = int(p)
my_files[s] = (head, number, idx)
# {"aA010.jpg" : (aa, 10, 0), "bddA23.jof" :("bdda",23,1),...}
# ----> 정렬 !!
file_list = my_files.items()
# [ ( "bddA23.jof" ,("bdda",23,1) ), ( {"aA010.jpg" ,(aa, 10, 0) ) ]
file_list = sorted(file_list, key = lambda x : (x[1][0], x[1][1], x[1][2]))
# [( {"aA010.jpg" ,(aa, 10, 0) ), ( "bddA23.jof" ,("bdda",23,1) )]
answer = [i[0] for i in file_list]
return answer
# test1
a = ["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]
solution(a)
#입력: ["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]
#출력: ["img1.png", "IMG01.GIF", "img02.png", "img2.JPG", "img10.png", "img12.png"]
# test2
a = ["F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"]
solution(a)
#입력: ["F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"]
#출력: ["A-10 Thunderbolt II", "B-50 Superfortress", "F-5 Freedom Fighter", "F-14 Tomcat"]
*** 오늘 했던 것들은
--> 이해를 하시고,,
본인 스타일로 정리
--> 연습을 통해서 손이 움직일 수 있도록 연습!!
*** 내일은 기본적인 내용 살짝 정리하고 -->
정렬 알고리즘 & 탐색 알고리즘!!
*** 꼭 !! 스스로 정리하세요!!
'ASAC 빅데이터 분석가 7기 > ASAC 일일 기록' 카테고리의 다른 글
ASAC 빅데이터 분석가 과정 6일차 - 2 (24.12.11) (1) | 2024.12.11 |
---|---|
ASAC 빅데이터 분석가 과정 6일차 - 1 (24.12.11) (0) | 2024.12.11 |
ASAC 빅데이터 분석가 과정 5일차 - 1 (24.12.10) (0) | 2024.12.10 |
ASAC 빅데이터 분석가 과정 4일차 - 2 (24.12.09) (0) | 2024.12.09 |
ASAC 빅데이터 분석가 과정 4일차 - 1 (24.12.09) (0) | 2024.12.09 |