ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2023-12-26
    스파르타/TIL(Today I Learned) 2023. 12. 27. 00:00

    SQLD 1주차 강의 요약

    SQLD는 SQL에 대해 잘 이해 하고 있는지에 관련된 국가 공인 자격증으로, 데이터 모델링과 SQL의 두가지로 크게 과목이 나눠져 있다. 데이터 모델링이란 데이터 처리를 하기전에 어떤 현태로 데이터를 저장, 구성할지에 관한 내용이고, SQL은 데이터베이스를 직접적으로 액서스하여 정의,조작,적용,취소,제어 등을 할 수있는 언어이다. 추가로 데이터는 저장이나 처리에 효율적인 형태로 변환된 정보를 데이터라고 하며, 그 데이터를 조직화하여 모은 것을 데이터 베이스라고 하며, 이것을 관리하는 프로그램을 DBMS라고 하며 종류에는 여러가지가 있지만, 우리가 배울 SQLD는 ORACLE(+ SQL Server)을 기반으로 출제되어있다.

     

    https://school.programmers.co.kr/learn/courses/30/lessons/142086 (가장 가까운 글자)

    아래 주석에 적어 놓은대로 처음 짠 것이 너무 오래걸려 다른 사람도 이렇게 오래걸리나 싶어 다른 사람의 코드도 확인해서 수정한 결과 index를 쓸 경우 검색하여 가장 먼저 나오는 값 하나만 나오는 것을 이용하였는데 항상 이런 것인지 이렇게 해도 되는 것인지는 확인해보지 않아서 불안정하다고 생각을 하고 있으며, 후에 확인하는 법을 생각해보고 확인해볼 생각이다. 그리고 여담으로 다른 문제도 풀고 하면서 깨달은 것이지만 아마 이문제가 연산시간이 오래 걸린 것은 아래에 서술한 다른 문제와 마찬가지로 슬라이스를 써서 때문에 아닌가 생각하고 있다.

    def solution(s):
        answer = []
        for i in range(len(s)):
            if s[i] not in s[:i]:
                answer.append(-1)
            else:
                answer.append((s[:i][::-1].index(s[i]))+1)
                #대신 살짝 불안정할수도 index해서 검색하여 값위치 찾을경우
                #가장 먼저나오는 값 위치 하나만 출력해주길래 그 점 이용
        return answer
    
    '''def solution(s): #처음에 짠 것 너무 오래걸려서 개선
        answer = []
        #print(s[:0])
        for i in range(len(s)):
            if s[i] in s[:i]:
                for j in range(len(s[:i])):
                    if s[i]==s[:i][::-1][j]:
                        answer.append(j+1)
                        break #가장 가까운 같은 글자 찾았으면 반복하면서 확인그만
                              #추가 확인하면 여러번 차이값을 답에 추가하게 됨     
            else:
                answer.append(-1)
        return answer'''
    
    '''def solution(s): #다른 분이 한것
        answer = []
        dic = dict()
        for i in range(len(s)):
            if s[i] not in dic:
                answer.append(-1)
            else:
                answer.append(i - dic[s[i]])
            dic[s[i]] = i
            print(dic)
        return answer'''

     

     

    https://school.programmers.co.kr/learn/courses/30/lessons/134240 (푸드파이터 문제)

    해당 문제를 풀다보니 리스트를 range를 이용하여 큰 수부터 작은수 순서로 만드는 법이 있었던 것 같은데 좀 긴가민가해서 range의 사용방법을 검색하여 다시 확인함

    크게 range(stop), range(start, stop), range(start, stop, step) 방식이 있고 stop은 어느숫자까지라는 의미이고(단 표현방식상 이 숫자 앞에 까지라는 의미로 받아드리면 좋을 듯하다.), start는 시작숫자, step은 간격 또는 차이를 의미한다. range(5)을 할 경우 0부터 4까지의 리스트가 생성 [0,1,2,3,4], range(1,5)을 할 경우 1부터 4까지 생성 [1,2,3,4], range(5,0,-1)를 하면 음수간격, 즉 감소하면서 5부터 시작하여 0전까지 생성한다 [5,4,3,2,1] 이렇게 된다. 옛날에 range의 정의 방식대로하면 stop은 생략이 안 되지만 start는 입력하지 않은채로 (default값사용) step을 입력하여 하는 방식도 가능했던 것 같은데 정확히는 기억이 안나며, 현재 다른 내용도 많이 시간이 적은 관계로 현재는 pass해두고 나중에 필요하거나, 시간이 여유가 있을 때 생각나면 찾아보도록하겠다.

    range() 함수의 결과는 반복가능(iterable)하기 때문에 for문을 사용해 출력가능하다

     

    https://school.programmers.co.kr/learn/courses/30/lessons/138477 (명예의 전당)

    해당 문제 풀이와는 크게 상관 없으나 for i in range():형태에서 아래 반복문중에 i+1의 형태가 떠올라 문득 옛날에 안 되었던 것으로 기억하는데 정확히 어땠더라 라는 호기심이 떠올라 어디에 메모해두고 잠깐 쉬는 시간에 파이썬으로 직접 테스트해보았다

    j=i+1
    for j in range(5):
    	print(i)
    	print(j)
    Traceback (most recent call last):
    File "F:/파이썬/range [test.py](<http://test.py/>)", line 4, in 
    j=i+1
    NameError: name 'i' is not defined

    안 되었던 걸로 기억하는데 혹시 해서 테스트해보니 역시 안됨 j=i+1라고 해주었지만 정작 i에 대해선 정의가 된 것이 없어 에러

    그래서 안 되는 것으로 기억은 하지만 혹시 몰라 간단한 추가 실험으로 순서를 조금 바꾸어 테스트 해주었다.

    for j in range(5):
    print(j)
    j=i+1
    print(i)
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #아래는 결과창을 복붙하여 붙인 것이다
    0
    Traceback (most recent call last):
      File "F:/파이썬/range test.py", line 8, in <module>
        j=i+1
    NameError: name 'i' is not defined

    역시 이것도 j가 값이 주어져 있긴 하나 변수를 기억하는 방식이 좌변이라는 이름에 우변의 값을 저장해두는 방식이기 때문에 i값이 주어지지 않아서 에러

     

    https://school.programmers.co.kr/learn/courses/30/lessons/159994 (카드뭉치)

    이 문제를 푸는데 두 카드 뭉치 중에서 해당차례에 해당하는 뽑기가 가능한지 확인하고, 뽑아내고서는 없기에 리스트에서 제거한다는 알고리즘을 이용하여 풀려는 생각을 하였기에, 리스트에서 원소를 제거하고자 했으나 바로 기억이 나지않아 다시 찾아보았다. 엄밀한 것은 자세히 살펴보지 않아 대략적인 사용법과 작용 결과만을 서술하자면, list.remove(해당원소)

    를 해주면 그 원소가 검색되어 첫번째로 나오는 해당 원소는 삭제된다(여러개가 존재할 경우 그냥 쓰면 가장 앞에 있는 하나만 제거된다). list.pop(인덱스) 인덱스를 생략할 경우 가장 마지막에 있는 원소가 출력되며 나옴으로써 리스트에서 제거된다, 인덱스를 적으면 해당 인덱스에 있는 원소가 출력되므로써 제거된다. 그리고 del은 del list[인덱스]의 방식으로 사용하며 해당 인덱스의 요소를 제거한다. 그외 여러방법이 더 있고, 각 방법과 메소드간의 차이가 있을 것인데, 자세한 것은 나중에 기회가 된다면 자세히 정리해보도록 할려고한다.

    처음코드는 에러가 뜨는데 

    def solution(cards1, cards2, goal):
        answer = ''
        for i in goal:
            if i == cards1[0]:
                cards1.remove(i)
                #del cards1[0]
                #cards1.pop(0)
                print(cards1)
            elif i == cards2[0]:
                cards2.remove(i)
                #del cards2[0]
                #cards2.pop(0)
                print(cards2)
            else:
                return "No"
                
        return "Yes"
    

    IndexError: list index out of range 에러 뜨는데 처음에는 왜 이런 에러가 뜨는지 이해하지 못하여 하나하나 print문을 통해 어디서 에러가 발생하는지 지점을 확인한 결과 이해할 수 있었다. 아래가 에러를 해결한 코드이다. (이유와 해결한 방법도 아래 후술)

    def solution(cards1, cards2, goal):
        for i in goal:
                if cards1[0] == i:
                    del cards1[0]
                    #cards1.remove(i)
                    #cards1.pop(0)
                    if len(cards1)==0:
                        cards1.append("0end")                               
                elif cards2[0] == i:
                    del cards2[0]
                    #cards2.remove(i)
                    #cards2.pop(0)
                    if len(cards2)==0:
                        cards2.append("0end")
            
                else:
                    return "No"
                
        return "Yes"
    

    코드의 내용을 간단히 설명하자면 위에서도 말했듯 해당하는 단어 카드가 뽑을 수 있을경우 뽑아 제거해 가는 방식으로 하였는데(후에 필요와 시간적 여유가 된다면 예시까지 추가해 보도록 하겠음) 앞의 순서에서 카드가 다뽑혀 더 이상 하나의 뭉치에 카드가 더 없게되면 리스트 안의 요소가 다 삭제되어 빈 리스트가 되는데 이 때 card~[0]은 정의될 수 없어서 에러가 난 것이다.

    따라서 에러를 방지하기 위해 빈 리스트가 되었을 때 아무 끝나는 단어를 빈리스트에 추가해준다(단, 입력할 때 값과 겹치면 안 되므로 문제조건인 문자열이 모두 알파벳소문자인 점을 적용하여 숫자+문자로 그 단어를 선정하였다) 그리고 테스트해본결과 del, remove, pop 세 개 전부 잘작동하였다

    https://school.programmers.co.kr/learn/courses/30/lessons/135808 (과일 장수)

    def solution(k, m, score): #시간이 오래걸려서 수정
        answer = 0
        score.sort(reverse=True) #리스트 내림차순으로 정렬
        for i in range(0,len(score),m): #m개씩 컷트
            if len(score[i:])>=m: #남은게 m개 이상일때만 진행
                answer+=score[i+m-1]*m #점수 추가하면서 계산
        return answer

    처음에는 위의 코드대로 작성해 주었는데 테스트 결과 몇몇 케이스들이 시간이 매우 오래 걸려 over time으로 실패가 떴다.

    예상으로 배열이 매우 긴 경우에 시간이 오래걸렸을 것이라 생각하였고, 왜 시간이 오래 걸리는지 예상이 되지 않아 다른 사람들이 해당 문제에서 질문한 것을 참고하여 실마리를 찾을 수 있었는데, 그 이유는 리스트의 slice(슬라이스)는 리스트의 길이에 비례하여 시간이 걸리기 때문이였다. 따라서 슬라이스 사용하는 부분을 다른 것으로 대처를 하면 연산시간을 많이 줄일 수 있을 것이라 생각하였고 그에따라 굳이 남은 갯수를 파악하는데 슬라이스한 리스트의 길이를 사용할 필요없이

    for 구문에서 쓰이고 있는 i를 이용하여 다른 방식으로 계산하여 처리해 주었고 아래와 같이 수정하였으며, 시간도 긴 배열에 대하여 굉장히 빨라졌다.

    def solution(k, m, score):
        answer = 0
        score.sort(reverse=True) #리스트 내림차순으로 정렬
        for i in range(0,len(score),m): #m개씩 컷트
            if len(score)-i<m: #남은게 m미만이면 중단
                break
            answer+=score[i+m-1]*m #점수 추가하면서 계산
        return answer

     

     

    '스파르타 > TIL(Today I Learned)' 카테고리의 다른 글

    2023-12-28  (1) 2023.12.28
    2023-12-27  (0) 2023.12.27
    2023-12-23  (0) 2023.12.23
    2023-12-22  (0) 2023.12.22
    2023-12-21  (0) 2023.12.21
Designed by Tistory.