본문 바로가기

카테고리 없음

[ 11/10 Today I Learned ] 알고리즘 기본 | 자료구조는 왜 배우는가? | OPEN API를 Ajax로 불러서 웹페이지 가공하기 실습

< 배열 내에서 내가 원하는 값이 있는지 찾는 함수 >

data = [3, 5, 6, 1, 2, 4]

def is_number_exist(number, array):
    for num in array:
        if number == num:
            return True
    else:
        return False

input_num = int(input('숫자 하나 입력해봐: '))
result = is_number_exist(input_num, data)
print(f'{input_num}은 array 안에 ' + ('있습니다.' if result else '없습니다.'))

 

사실 간단한 알고리즘이지만.

 

어제 배운 따끈따근한  for-else 문 .  f-string과 if-else 을 한 줄에 쓰는 것이 너무 맘에 들어

 

남겨놓은 코드이다. 역시 배운걸 바로바로 써먹는 재미가 쏠쏧하다 ㅎㅎ

 

 

또한 하나의 생각 추가

 

if max == 0 or right_val == 0:  # 왼쪽 값 or 오른 쪽 값이 0일 경우, *을 하면 값이 0이 된다.
    max += right_val  # 왼쪽 값 + 오른쪽 값
elif max == 1 or right_val == 1:    # 오른쪽 값이 1인 경우, 곱해봤자 값이 똑같으니 더해준다. + 지금까지 더한 값이 1이어도, 더해줘야한다.
    max += right_val

 

이 코드를 좀 더 짧게하면?

 

if max <= 1 or right_val <= 1:  # 왼쪽 값 or 오른 쪽 값이 0 or 1일 경우, *을 하면 손해!
    max += right_val  # 왼쪽 값 + 오른쪽 값

 

이렇게 간단하게 고칠 수 있는 것이었다.

동일한 연산을 하는 if / elif 구문에 대해서, 조건을 합쳐줄 수 없는지 고민해봐야겠다는 깨달음이 있었다.

 

< 주어진 배열에서 더하기 or 곱하기를 사용해서, 가장 큰 수를 만드는 알고리즘 >

 

문제 설명 : 주어진 배열의 값에서, 곱하기 or 더하기만 사용해서 가장 큰 값을 만드는 함수 만들기.

( 단 주어진 배열의 element는 0 또는 양의 정수 )

input = [0, 1, 5, 6 ]


# 입력 값은 0 혹은 양의 정수


def find_max_plus_or_multiply(array):
    # 더하기 또는 곱하기

    # 시작하는 값이 0인 경우 => 무조건 더하기
    # 오른쪽의 값이 0인 경우 => 무조건 더하기
    # 오른쪽의 값이 1인 경우 => 무조건 더하기
    # 총 합이 1인 경우 => 무조건 더하기
    # 나머지 경우 => 전부 다 곱하기


    max = array[0]   # array 처음 값으로 초기화

    for x in range(len(array)-1):   # array 의 길이만큼 연산. O(N)의 시간복잡도를 갖는다.
        right_val = array[x+1]
        if max <= 1 or right_val <= 1:  # 왼쪽 값 or 오른 쪽 값이 0 or 1일 경우, *을 하면 손해!
            max += right_val  # 왼쪽 값 + 오른쪽 값
        else:
            max *= right_val    # 오른쪽 값이 0 or 1 이 아닌 경우, 양의 정수니까 곱해준다.

    return max


result = find_max_plus_or_multiply(input)
print(result)

 

 

< 반복되지 않는 문자 >

 

문제 설명 : 영어로 되어 있는 문자열이 있을 때, 이 문자열에서 반복되지 않는 첫번쨰 문자를 반환하라.
만약 그런 문자가 없다면 _를 반환하라.

 

[ 내가 푼 풀이 ]

input = "abccddeeabazzq"

def find_not_repeating_character(string):
    is_not_repeated = [True]*len(string)   # 배열의 요소들이 반복되었는지 여부를 체크하는 마크 배열
    first_not_repeating_char = '_'  # 아래 반복문을 통해, 반복되지 않는 문자가 없을 때 return 할 Default Value

    for fixed_idx in range(len(string)):    # O(N^2)

        if fixed_idx == len(string) - 1 and is_not_repeated[fixed_idx]: # 마지막 값은 아래 for문에서 커버 못쳐준다.
            return string[fixed_idx]

        if is_not_repeated[fixed_idx]:  # 지금 비교할 문자열이 반복되지 않았다면
            for compared_idx in range(fixed_idx+1, len(string)):    # 그 이전 것들은 볼 필요가 없으니, 뒤에 것들이랑 비교를 한다.
                if string[fixed_idx] == string[compared_idx]:
                    is_not_repeated[fixed_idx] = False
                    is_not_repeated[compared_idx] = False
                    continue
                elif compared_idx == len(string) - 1 and is_not_repeated[fixed_idx]:    # 배열의 마지막 요소까지 비교했고, 그럼에도 반복되지 않은 문자라면
                    first_not_repeating_char = string[fixed_idx]
                    return first_not_repeating_char # 여러가지 배열의 요소들이 반복되지 않은 문자일 수 있으니, 그 중 첫번째 문자를 return 해준다.

    return first_not_repeating_char




result = find_not_repeating_character(input)
print(result)

 

< 입력된 수 보다 작은 소수들을 출력하는 알고리즘 >

- 개선의 여지가 좀 있다

( = 모든 요소들을 도는 것이 아니라, 소수로만 나눠주는 것이 필요 ! , 어차피 소수가 아닌 수들은 합성수고 = 이는 소수의 곱으로 나타낼 수 있기 때문이다 / 연산의 횟수를 줄일 수 있다. )

 

" 모든 알고리즘은 개선 가능하다 "

 

def find_prime_list_under_number(number):

    prime_list_under_number = []

    if number < 2:
        return prime_list_under_number

    is_prime = False

    for x in range(1, number+1):   # 1부터 number 까지의 수 까지.
        if x == 1:
            continue
        is_prime = True
        for y in range(1, x):
            if y == 1:
                continue
            if x % y == 0:
                is_prime = False
                break
        if is_prime:
            prime_list_under_number.append(x)

    return prime_list_under_number


input = 100
result = find_prime_list_under_number(input)
print(result)

 

< 문자열 뒤바꾸기 >

 

# Q.
# 0과 1로만 이루어진 문자열이 주어졌을 때, 이 문자열에 있는 모든 숫자를 전부 같게 만들려고 한다. 할 수 있는 행동은 문자열에서 연속된 하나 이상의 숫자를 잡고 모두 뒤집는 것이다.
# 뒤집는 것은 1을 0으로, 0을 1로 바꾸는 것을 의미한다.
#
# 예를 들어 S=0001100 일 때,
#
# 전체를 뒤집으면 1110011이 된다.
# 4번째 문자부터 5번째 문자까지 뒤집으면 1111111이 되어서 2번 만에 모두 같은 숫자로 만들 수 있다.
# 하지만, 처음부터 4번째 문자부터 5번째 문자까지 문자를 뒤집으면 한 번에 0000000이 되어서 1번 만에 모두 같은 숫자로 만들 수 있다.
#
# 주어진 문자열을 모두 0 혹은 모두 1로 같게 만드는 최소 횟수를 반환하시오.


def find_shortest_trial_to_unify(string):

    continuity_counter = {"zero_continuity": 0, "one_continuity": 0}

    for idx in range(len(string)):
        if idx == len(string) - 1:
            if string[idx] == string[idx - 1]:
                if string[idx] == '0':
                    continuity_counter['zero_continuity'] += 1
                    break
                elif string[idx] == '1':
                    continuity_counter['one_continuity'] += 1
                    break
            elif string[idx] != string[idx - 1]:
                continuity_counter['zero_continuity'] += 1
                continuity_counter['one_continuity'] += 1
                break

        left = int(string[idx])
        right = int(string[idx + 1])

        if (left == 0 and right == 0) or (left == 1 and right == 1):
            continue
        elif left == 0 and right == 1:
            continuity_counter['zero_continuity'] += 1
        elif left == 1 and right == 0:
            continuity_counter['one_continuity'] += 1

    num_of_zero_con = continuity_counter['zero_continuity']
    num_of_one_con = continuity_counter['one_continuity']

    return num_of_zero_con if num_of_zero_con <= num_of_one_con else num_of_one_con


example1 = "00001000"
example2 = "01011000"
example3 = "01010100"
example4 = "01010101000010101001001"

result1 = find_shortest_trial_to_unify(example1)
result2 = find_shortest_trial_to_unify(example2)
result3 = find_shortest_trial_to_unify(example3)
result4 = find_shortest_trial_to_unify(example4)

print(f'1번째 문자열 횟수 = {result1} \n2번째 문자열 횟수 = {result2} \n'
      + f'3번째 문자열 횟수 = {result3} \n4번째 문자열 횟수 = {result4}')

 

* 알고리즘을 짜면서 느낀 점 & 배운 점 *

 

1) 코딩은 재밌다. 생각하는 과정은 머리 아프고 복잡하긴 한데, 차근차근 문제를 해결해나가는 것이 재밌다.

눈에 보이는 변화가 느껴지니까. 디버깅하는 것도 즐겁다.

 

2) 한 줄이라도 더 짧게, 한 연산이라도 덜 하게. 효율적이게 코드를 짜고 싶다.

개발할 때 팀원들끼리 커뮤니케이션을 할 일이 많을텐데, 팀원들이 읽기 쉽고 이해하기 쉬운 코드를 짜는 것이

팀원들을 향한 나의 배려이니까. 그리고 그렇게 짜는 과정에서 내 사고력도 느는 느낌이다.

 

3) 예외처리는 매우 중요하다. 경우의 수를 많이 생각해봐야한다.

 

=======================

 

[ 자료구조는 왜 배워야하는가? ]

 

어떤 자료구조는 탐색이 빠르고,

 

어떤 자료구조는 삽입/삭제가 빠르다.

 

서비스에서 사용할 CRUD 연산을 설계한 후, 그에 최적화된 자료구조를 골라서 개발하면

 

개발하는데 효율적이고, 성능/개발 속도의 향상을 기대할 수 있다.

 

그렇기에 자료구조를 미리미리 배워두는 것!

 

========================

 

< OPEN API 사용 코드 Ajax를 통한 실습 >

 

function print_star(num_of_stars) {
    if (num_of_stars == 1)
        return '⭐'
    else if (num_of_stars == 2)
        return '⭐⭐'
    else if (num_of_stars == 3)
        return '⭐⭐⭐'
    else if (num_of_stars == 4)
        return '⭐⭐⭐⭐'
    else if (num_of_stars == 5)
        return '⭐⭐⭐⭐⭐'
}

$(document).ready(function () {
    $.ajax({
        method: "GET",
        url: "http://spartacodingclub.shop/web/api/movie",
        data: {},
        success: function (response) {
            let rows = response['movies']
            console.log(rows)

            for (i = 0; i < rows.length; i++) {
                temp_html = `<div class="col">
                              <div class="card">
                                    <img src=${rows[i]['image']} class="card-img-top" alt="...">
                                <div class="card-body">
                                    <h5 class="card-title">${rows[i]['title']}</h5>
                                    <p class="card-text">${rows[i]['desc']}</p>
                                    <p>${print_star(rows[i]['star'])}</p>
                                    <p class="mycomment">${rows[i]['comment']}</p>
                                </div>
                            </div>
                         </div>`
                $('#cards-box').append(temp_html)
            }
        }
    })
});

 

아직 웹개발 종합반 3~5주차를 안들었기에, 좀 남겨놨었는데

 

담주 금욜날부터 시작하는 프젝을 위해 완강해야겠다!

 

웹개발 종합반 1~2주차에서 배운 HTML / CSS / JavaScript / jQuery / Ajax 를 사용하는 그런 실습문제였는데

 

아무 도움 없이! 나 혼자 코드를 짰고, 돌아가는 것을 확인했다 ㅎㅎ

 

만족스러웠다 :)