10일차 TIL : 알고리즘 1주차

변시윤·2022년 11월 9일
0

내일배움캠프 4기

목록 보기
10/131

학습내용

  • 알고리즘
    • 개념정리
    • 배열의 최대값 반환
    • 알파벳 빈도수 반환

배열의 최대값 반환

Q. input = [3, 5, 6, 1, 2, 4]에서 값이 가장 큰 요소를 반환하기

이중반복문

2개의 숫자를 비교해서 최대값을 출력하는 방법

def find_max_num(array):
    for num in array:
        for compare_num in array:
            if num < compare_num:
                break
        else:
            return num

result = find_max_num(input)
print(result)
> 6
  1. array = 매개변수 = input이 들어가는 자리
  2. input의 요소들을 num이라는 이름으로 반복
  3. num과 비교할 요소를 compare_num에 할당
  4. num < compare_num -> num에 다음 요소 할당
  5. num > compare_num -> 현재 num에 할당된 요소를 리턴
    • else
      for문이 끝날 때까지 아무런 값도 출력되지 않았을시 실행되는 구문으로 조건문 if가 아닌 for문과 상응한다.

지정변수

요소를 담을 변수를 지정해서 다른 요소와 비교하는 방법

def find_max_num(array):
    max_num = array[0]
    for num in array:
        if num > max_num:
            max_num = num

    return max_num

result = find_max_num(input)
print(result)
>6
  1. max_num에 배열의 초기값 할당 = 3
  2. 반복문으로 배열의 다른 요소들을 num에 할당 후 비교
  3. num > max_num-> max_num의 값을 num으로 변경
  4. 반복문 종료 후 max_num을 반환

정렬함수

배열을 오름차순으로 재정렬한 후에 마지막 요소 반환

def find_max_num(array):
    lastValue = sorted(array)[-1]
    
    return lastValue

result = find_max_num(input)
print(result)
> 6

이건 강의에 나온 내용은 아니고 내가 작성한 답안이다. 아무리 생각해도 강의에서 배운 내용보다 이쪽이 훨씬 직관적이고 간결한 것 같은데 왜 강의에서는 굳이 반복문을 돌리는 건지 이해가 되질 않았다. 반복문으로 해결하는 방법을 배우는 시간이었다면 이해가 가는데 파이썬 강의가 아니라 알고리즘 강의였으니까. 그래서 튜터님께 질문을 드렸는데 경우에 따라서는 풀어서 쓰는 게 오히려 더 쉽고 빠를 수도 있지만 코딩테스트 때는 시간이 제한적이기 때문에 대부분 간결하게 작성한다는 답변을 받았다. 그말인 즉슨... 나의 답안이 모범답안이라는 거겠지....!!!



알파벳 빈도수 반환

Q. 알파벳별 빈도수를 리스트로 반환하기

아스키코드로 알파벳 순서 반환하기

def find_alphabet_occurrence_array(string):
    alphabet_occurrence_array = [0] * 26

    for char in string:
        if not char.isalpha():
            continue
        arr_index = ord(char) - ord("a")
        alphabet_occurrence_array[arr_index] += 1

    return alphabet_occurrence_array


print(find_alphabet_occurrence_array("hello my name is sparta"))
[3, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 2, 2, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 0]
  1. 알파벳별 빈도수를 리스트로 저장하기 위해서 알파벳 길이와 같은 초기 배열 생성
    ex) 0 = a, 1 = b, 2 = c ...
  2. 인수로 받은 문장을 for문으로 돌면서 빈도수 체크
  3. isalpha()로 문자열 여부를 판별해서 띄어쓰기에 해당될 경우 다음 문자로 continue
  4. 알파벳별 순서값을 arr_index로 할당
  5. 알파벳이 포함될 때마다 각각의 알파벳이 해당되는 순서에 1씩 누적
    • ord() : 문자열을 아스키 코드로 변환하는 파이썬 내장함수
      alphabet_occurrence_array의 요소들은 알파벳 순서에 해당되므로 특정 알파벳의 빈도수를 리스트에 포함시키기 위해선 해당 알파벳에 상응하는 순서값을 알아야 한다. 알파벳은 문자이기 때문에 이를 숫자로 변환해야 하는데 이 경우 보통 아스키 코드를 사용한다.
      a의 아스키코드값은 97이고 z의 아스키코드값은 122로 뒷순서에 해당될수록 값이 커진다. 이런 특성을 활용해 비교 알파벳의 아스키값 - a의 아스키값을 계산하면 해당 알파벳의 순서값을 구할 수 있다.
    • ord('a') - ord('a') = 97-97 = a는 리스트의 0번째 요소에 해당
    • ord('b') - ord('a') = 98-97 = b는 리스트의 1번째 요소에 해당

Q. 가장 많이 포함된 알파벳을 반환하기

매개변수로 받은 문장의 알파벳과 알파벳 리스트 요소의 일치 빈도수 확인하기

def find_max_occurred_alphabet(string):

    alphabet_array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
                      "t", "u", "v", "x", "y", "z"]

    max_occurrence = 0
    max_alphabet = alphabet_array[0]

    for alphabet in alphabet_array:
        occurrence = 0
        for char in string:
            if char == alphabet:
                occurrence += 1
        
        if occurrence > max_occurrence:
            max_occurrence = occurrence
            max_alphabet = alphabet

    return max_alphabet


result = find_max_occurred_alphabet("I gotta find out!")
print(result) 
> t
  1. 알파벳을 문자열로 돌리기 위한 알파벳 리스트 alphabet_array 생성
  2. 최다 빈도수값을 담을 변수 max_occurrence를 생성 후 초기값 부여
  3. 최다 빈도수에 해당되는 알파벳을 담을 변수 max_alphabet을 생성 후 초기값 부여
  4. alphabet_arrayfor문으로 하나씩 돌리기
  5. 반복문 안에서 다시 인수로 받은 문장의 알파벳 요소를 반복문으로 돌리기
  6. 인수로 받은 문장의 알파벳과 alphabet_array의 알파벳이 일치할 때마다 해당 occurrence의 값을 1씩 누적
  7. max_occurrencemax_alphabet에 최빈값과 최빈값에 해당되는 알파벳 할당
  8. max_alphabet 반환

매개변수 문장의 알파벳과 리스트 요소의 일치 빈도수 반환 후 최다 빈도값에 해당되는 알파벳을 아스키코드로 변환하기(앞서 사용한 두 가지 방식을 혼합)

def find_alphabet_occurrence_array(string):
    alphabet_occurrence_array = [0] * 26

    for char in string:
        if not char.isalpha():
            continue
        arr_index = ord(char) - ord("a")
        alphabet_occurrence_array[arr_index] += 1

    max_occurrence = 0
    max_alphabet_index = 0

    for index in range(len(alphabet_occurrence_array)):
        alpahbet_occurrence = alphabet_occurrence_array[index]

        if alpahbet_occurrence > max_occurrence:
            max_occurrence = alpahbet_occurrence
            max_alphabet_index = index
        
        ascii = chr(max_alphabet_index + ord('a'))
        result = (f'{max_alphabet_index}번째 알파벳 {ascii}은(는) 총 {max_occurrence}개가 포함되었다.')


    return result


print(find_alphabet_occurrence_array("every single tiny word"))
> 4번째 알파벳 e은(는) 총 3개가 포함되었다.

1 .Q.알파벳별 빈도수를 리스트로 반환하기 와 동일한 과정
2. 최다 빈도수값을 담을 변수 max_occurrence를 생성 후 초기값 부여
3. 최다 빈도수값에 해당되는 인덱스를 담을 변수 max_alphabet_index를 생성 후 초기값 부여
4. 알파벳 빈도수 배열 alphabet_occurrence_array을 반복문으로 돌려서 인덱싱 생성
👉🏻 print(index) 실행시 0부터 25까지 순차적으로 나열

  • range() 연속된 정수를 생성하는 함수
  • len() 문자열 길이 반환

range(len(alphabet_occurrence_array))인 이유
배열의 길이만큼 순차적으로 나열된 정수 리스트가 필요한데 range()는 매개변수로 정수만허용하기 때문에 리스트인 alphabet_occurrence_array는 매개변수가 될 수 없다. 그렇기 때문에 len()으로 리스트의 길이를 정수로 반환해준 것이다.

5 . 알파벳 빈도수 정보를 alphabet_occurrence에 할당
ex) alphabet_occurrence_array[3] = 1, alphabet_occurrence_array[4] = 3 ...
6. 새로 할당한 알파벳 빈도수 alphabet_occurrencemax_occurrence보다 클 경우, max_occurrencemax_alphabet_index에 최빈값과 최빈값에 해당되는 인덱스 정보 할당
7. max_alphabet_index는 아스키코드를 숫자로 변환한 값이므로 다시 문자로 변환




하....................................................................................쉽지 않다 알고리즘...........ㅎ
일단 어찌어찌 간신히 이해하긴 했는데 진도가 너무 늦게 나가서 곤란하다. 이 속도로는 일정내에 다 소화할 수가 없다... 시간내에 목표 진도 다 못나간 건 개강 이후로 오늘이 처음이다ㅠ.ㅠ 그래도 초반은 할만 했는데 최빈값 찾기 파트부터는 갑자기... 갑자기......... .......... ... . ...... ..... .. . .. .... . .. . ..... ...뭐랄까.... 영양제를 적당히 먹으면 몸에서 흡수하지만 한꺼번에 많이 섭취하면 소변으로 다 배출되는 경험을 다들 한 번쯤 해봤을 것이다. 이게 공부에도 적용이 될 수 있다는 걸 오늘 처음 알았다...... 개발 공부하면서 막막해지는 기분 정말 간만이다...ㅎ 강의명이 알고보면 알기쉬운 알고리즘인데 알고보니 더어려운 알고리즘으로 강의명을 변경하는 건 어떨지 스파르타측에 건의하고 싶다... ㅎ........ 이번주에는 무슨 일이 있어도 깃헙이랑 피그마 사용법을 익히려고 했는데 당장 알고리즘 진도 소화하는 것도 빡셀 것 같다. 크흡....

profile
개그우먼(개발을 그은성으로 하는 우먼)

2개의 댓글

comment-user-thumbnail
2022년 11월 10일

아무래도 변수명부터 익숙하지 않은것들을 사용하기도하고 (명시적이지만)
모르던 개념들이 나오셔서 힘드실 수 있습니다 (저 또한 비슷한 경험을....)
너무 조급해마시고 천천히 화이팅입니다

1개의 답글