본문 바로가기

TIL

[240221] SQL: 코드카타 125~126(regexp) & 파이썬: 코드카타 33

[SQL 코드카타]

1517. Find Users With Valid E-Mails

https://leetcode.com/problems/find-users-with-valid-e-mails/

 

1) 어떤 문제가 있었나

주어진 조건에 맞는 유효한 이메일 주소를 출력하는 문제

(조건)

- 이메일id는 영문, 숫자, 언더바(_), 점(.), 대쉬(-)로만 구성 

- 이메일id 첫 글자는 무조건 영문으로 시작

- 도메인 주소는 @leetcode.com

2) 내가 시도해본 건 무엇인가

like '%~' 로는 도메인 주소만 걸러낼 수 있어서, 영문과 숫자 등 여러 조건을 포함 할 수 있는 함수 구글링

> REGEXP 발견하여 적용해보았으나, #(샾) 특수문자가 포함된 메일을 걸러내지 못해서 실패 

select user_id, name, mail
 from Users
 where mail like '%@leetcode.com'
       and mail REGEXP '[a-z]|[A-Z]|[0-9]|_|.|-'
       and substring(mail,1,1) REGEXP '[a-z]|[A-Z]'

 

3) 어떻게 해결했나

다른 사람 풀이를 확인하여 REGEXP의 정규식을 활용한 풀이를 확인

# 정답 쿼리 
select user_id, name, mail
 from Users
 where mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*@leetcode[.]com'

# 의문점 
# 1-Q 도메인을 like 절로 빼서 쓰면 왜 [quarz#2020@leetcode.com]는 안 걸러지는 걸까 
# 1-A $로 문자를 끝내지 않았으니 #와도 넘겨주는 듯
select user_id, name, mail
 from Users
 where mail like '%@leetcode.com' 
       and mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]'
       
#2-Q *@leetcode[.]com / 이 부분에서 왜 *를 붙이고, 점 앞뒤에 []가 필요한 걸까
#2-A 도메인 앞에 뭐든 문자열이 오고, .은 정규식에서 임의 문자의 의미가 어 정확히 점이 들어가야 함을 표기


4) 무엇을 새롭게 알았나
- regexp 함수

: 정규식을 이용해 like 보다 세부적인 조건을 걸 수 있는 검색 방식 

: (구조) where 칼럼명 regexp '정규식' 

: 정규식 기호 안내 및 풀이 

문자 설명 사용 예시 의미
. 임의의 문자  '^..$' 2음절인 문자
* * 앞 패턴이 0번 이상 반복  '[AZ]*' 대문자 A~Z 0번 이상 반복
+ + 앞 패턴이 1번 이상 반복  '[AZ]+' 대문자 A~Z 1번 이상 반복
^ 문자열의 시작을 의미 '^[AZ]' 대문자 A~Z로 시작 
$ 문자열의 끝을 의미 '[09]$' 0~9 숫자로 종료 
[ abc ] [] 안에 있는 문자와 정확히 일치 'email[.]com' 문자가 정확히 email[.]com과 일치
[^abc] [] 안에 있는 문자가 속하지 않음 '^([^Dd])' 시작 문자열이 D나 d가 아님 
{n} 앞에 위치한 패턴이 n회 반복 '^([Dd]){2}' 시작 문자열이 D나 d가 2번 반복
{n, m} 앞에 위치한 패턴이 n회 이상, m회 이하 반복 '^([Dd]){2, 4}.$' 시작 문자열에 D나 d가 2~4번 반복
| or '가|나|다' 가 또는 나 또는 다를 포함

 

* 참고

https://steemit.com/mysql/@seobangnim/mysql-regexp /

https://dev.mysql.com/doc/refman/8.0/en/regexp.html

 


[파이썬 코드카타]

약수의 개수와 덧셈

https://school.programmers.co.kr/learn/courses/30/lessons/77884

 

1) 어떤 문제가 있었나

주어진 범위의 숫자가 약수 개수가 짝수이면 더해주고, 홀수이면 빼주는 문제 

 

2) 내가 시도해본 건 무엇인가

for와 if문을 여러번 활용하여, 맨 처음 적용한 for문의 num 숫자가 마지막 anwer 값으로 적용 완료된 후,

다시 첫 for문의 다음 num 숫자가 동일한 루프를 돌기를 희망하였으나 중간에서 누적값이 적용됨

left = 13 
right = 17
divisor = 0 
answer = 0

for num in range(left, right+1):  #13~17
    for i in range(1, num+1):  #1~13, 1~14.. 
        if num % i == 0:
            divisor += 1
            if  divisor % 2 == 0: 
                answer += num 
            else: 
                answer -= num 

print(answer) # -16

 

3) 어떻게 해결했나

- chat GPT에게 문제를 문의하였더니, divisor 변수가 내부 루프가 돌 때마다 0으로 초기화 되어야 한다고 답변

def solution(left, right):
    answer = 0         # for문 밖에 있어서, for문이 돌 때마다 값이 누적됨      
    for num in range(left, right+1):  
        divisor = 0      # 내부루프에 변수를 위치시켜, for문에서 값을 뺄 때마다 값을 초기화
        for i in range(1, num+1):  
            if num % i == 0: 
                divisor += 1   # 13에 대한 divisor는 2 저장된 후 다음 루프에 초기화
        if divisor % 2 == 0:  # 약수의 개수나 도출된 다음에, 홀짝 판별하여 answer에 num값 추가/제외 
            answer += num 
        else: 
            answer -= num 
    return answer


4) 무엇을 새롭게 알았나

- 변수의 위치를 안과 밖 중 어디에 두느냐에 따라 값이 완전히 달라짐 

└ 변수가 함수나 루프 밖에 있으면, 외부 루프에 의해 계속 누적됨

└ 변수가 함수나 루프 안에 있으면, 선언된 위치와 값에 맞춰 초기화