본문 바로가기
WIL&TIL/TIL

20230424 TIL - 알고리즘

by 코드뭉치 2023. 4. 24.

 

1.  

문자열 정렬하기

더보기

 1. isdigit()

def solution(a):
    # # 리스트를 하나 만들어서 a문자열을 돌면서 문자열이 숫자인지 확인
    # # 숫자라면 리스트에 int값으로 추가해주기
    result = []
    for i in a:
        if i.isdigit():
            result.append(int(i))
    # 정렬
    return sorted(result)

 

2. isnumeric()

 > isdigit과의 차이점은 isdigit()은 0~9의 아라비아 숫자만을 판별(ex. ²도 가능)
    isnumeric()은 ½처럼 유니코드 기반의 모든 숫자가 들어간 문자열을 판별해줄 수 있다.

def solution(a):
    answer = []
    for i in my_string:
        if i.isnumeric() : answer.append(int(i))
    answer.sort()
    return answer

 

3. try except

    int(i)는 i가 정수형이 아닐 경우, ValueError가 발생한다. ValueError일때만 except로 처리해주는 방법.

def solution(a):
    # a 문자열을 돌면서 int(i)를 해주는데, 만약 문자열이면 ValueError 발생
    # try except로 예외처리
    result = []
    for i in a:
        try:
            result.append(int(i))
        # 에러 발생 시 다음 원소부터 다시 리스트에 넣기
        except ValueError: 
            continue
        # 정렬
    return sorted(result)

 

2.

겹치는 선분의 길이

더보기

0. 하려고 했던 방법(결국 못품)

num_dict라는 딕셔너리에 {(각각 선의 번호) : [해당 선이 지나는 점들]}

ex) {0: [0, 1, 2], 1: [3, 4, 5], 2: [1, 2, 3, 4, 5, 6, 7]}

이런 방식으로 넣어서 겹치는 선분의 길이를 찾아보려고 시도.

 

그러나 중복 처리를 할 때, A, B, C 선분이 있다고 하면 한 선분이 나머지 두개의 선분과 모두 겹쳐질 때를 어떻게 예외처리해야할지 찾아내지 못함.

def solution(lines):
    num_dict = {}
    for i in range(len(lines)): 
        for dot in range(lines[i][0], lines[i][1]):
            if i in num_dict.keys():
                num_dict[i].append(dot)
            else:
                num_dict[i] = [dot]
    length = []

    for i in range(len(num_dict.keys())):
        length += num_dict[i]
    a = len(length)
    b = len(set(length))

 

1. 팀원분이 푸신 방법

    점과 점 사이의 x.5를 지나는 선이 여러개라면 겹치는 부분.

    리스트에 x.5를 모두 집어넣고, set()으로 중복값을 제거하여

    겹치는 선의 x.5들 중 중복을 제거한 개수(count() 사용)를 반환하는 방법

def solution(lines):
    answer = 0
    # 직선의 중심인 x.5를 지나는 선이 여러개면 겹치는 부분임
    # 리스트에다가 x.5를 구해서 다 집어넣자
    arr = []
    for i in lines:
        for j in range(i[0],i[1]):
            arr.append(j+0.5)
            
    # arr의 중복제거를 위해 set으로 만들고
    # for문으로 count해서 1이 아니면 answer를 1씩 늘림
    for i in set(arr):
        if arr.count(i) != 1 : answer+=1
	return answer

 

2. 찾아본 다른 풀이

def solution(lines):
    sets = [set(range(min(l), max(l))) for l in lines]
    return len(sets[0] & sets[1] | sets[0] & sets[2] | sets[1] & sets[2])

일단 0번에서 내가 하려고 했던 각각의 선분이 지나는 점을 range()와 min, max를 사용해서 바로 구함.

ex) sets = [{0, 1, 2, 3, 4}, {3, 4, 5, 6, 7, 8}, {1, 2, 3, 4, 5, 6, 7, 8, 9}]

 

이런 형태로 나오게 되는데, 여기서 각각을 인덱싱해서 집합 연산자를 사용해서 각각의 교집합들의 합집합을 구함.

이렇게 하면 집합이기 때문에 중복값들은 알아서 걸러지고 코드도 간결해진다.

 

 

3.

로그인 성공

더보기

1. 리스트도 하나의 원소이므로 in을 사용해서 db안에 있는지 먼저 판별, 있다면 "login"을 반환

    처음 if문에서 id와 비밀번호가 모두 일치할 경우 리턴을 해줬기 때문에,

    for문에 들어오는 값들 중 id가 일치한 값들은 pw가 틀린 것들이다. 

    db의 각각의 리스트에 대해서  0번째 인덱스, 즉 id가 일치하는 항목이 있는지 판별하여 있다면 "wrong pw" 반환

    없을 경우 for문을 한바퀴 돌 때까지 continue.

 

    for문이 끝날 때까지 id가 일치하는 회원이 없다면 "fail"을 반환

def solution(id_pw, db):
    if id_pw in db:
        return "login"  
    for row in db:
        if row[0] in id_pw[0]:
            return "wrong pw"
        else:
            continue
    return "fail"

 

 2. id일치를 먼저 검사하고, 그 값들 중 pw를 검사하는 방법

    break를 통해 불필요한 연산을 즉시 종료할 수 있다

def solution():
	# 기본값을 'fail'
    answer = 'fail'
    # for 문으로 db안의 요소들을 검사
    for i in db:
        if i[0]==id_pw[0]: 
            if i[1]==id_pw[1]: 
                answer = 'login'
                break
            else: 
                answer = 'wrong pw'
                break
    return answer

 

3. id 리스트, pw 리스트로 분리해서 각각의 자료를 비교해서 값을 반환

def solution(id_pw, db):
    ids = []
    pws = []
    for i in db:
        ids.append(i[0])
        pws.append(i[1])
    if id_pw[0] not in ids:
        answer = "fail"
    elif id_pw[1] != pws[ids.index(id_pw[0])]:
        answer = "wrong pw"
    else:
        answer = "login"
    return answer

 

4.

부분 문자열인지 확인하기

더보기

 1. 삼항 연산자, bool값으로 풀기

   target in my_string으로 가장 기본적인 방법으로, bool값을 반환하므로 if로 판별하기.

   int(true) 1이므로 target in my_string 자체에 int를 걸어서 1 또는 0을 반환하는 방법.

def solution(my_string, target):
    return 1 if target in my_string else 0

def solution(my_string, target):
    return int(target in my_string)

 

2.  find(i)는 문자열에서 i의 인덱스를 반환한다.(없으면 -1 반환)

    문자열안에 해당 값이 없다면 -1을 반환하므로, .find(target) >= 0일 때, 1을 반환

    없다면 -1이므로 else문으로 0을 반환 

def solution():
    if my_string.find(target)>=0: 
        answer = 1
    else:
        answer = 0
    return answer

 

3.  for문 사용하는 방법

    my_string[i:i+len(target)]은 "banana"문자열이면

    "ban", "ana", "nan", "ana"

    이런 식으로 잘라서 target과 일치하는지 비교

    역시 값이 나오면 바로 break로 탈출

def solution():
    answer = 0
    for i in range(len(my_string)-len(target)+1):
    	if my_string[i:i+len(target)] == target: 
        	answer = 1
        	break
    return answer

 

 

 

댓글