[항해] 알고리즘_1주차

Jeon·2021년 6월 12일

알고리즘

목록 보기
3/33

내가 헷갈리는 것

1. range
range는 list 내에서 원소의 시작점~종료점까지 쭉 나열하는 것
EX)

for a in range(5):
...     print(a)
...
0
1
2
3
4
**Note that range(5) is not the values of 0 to 5, but the values 0 to 4.**
for a in range(3,6):
...     print(a)
...
3
4
5

range는 이렇듯 반복문(for)과 자주 쓰이고, range 안의 요소 갯수만큼 반복하여 요소를 하나씩 꺼내어줌. 0, 1, 2, 3, 4 이렇게 다섯가지를 하나씩 꺼내줌!!
주의 : range(0,5)는 0,1,2,3,4 // 만약 1,2,3,4,5 를 꺼내고 싶으면 range(1,6)

2. len

a = 'abcd'
print(len(a)) ===== 4

3. range와 len의 조합

a = 'abcd'
print(len(a)) # ==4
print(range(len(a))) # == range(0, 4)
for i in range(len(a)): # == a에서 0, 1, 2, 3번째 요소를 꺼내어 하나씩 출력!!
	print(a[i]) === a, b, c, d
** for i in range(len(a)-1): == a에서 0, 1, 2번째 요소를 꺼내어 하나씩 출력!!
	print(a[i])

알고리즘 문제 정리

1. 리스트에서 최대값 찾기
1안)

input = [3, 5, 6, 1, 2, 4]
def find_max_num(array):
    for num in array: #N 1회
        for compare_num in array: #N 2회
            if num < compare_num: #비교연산 1회
                break
        else:
            return num
result = find_max_num(input)
print(result)

시간복잡도 : N^2


2안)

input = [3, 5, 6, 1, 2, 4]
def find_max_num(array):
    max_num = array[0]
    for num in array: #N 1회
        if num > max_num: #비교연산 1번
            max_num = num #대입연산 1번
    return max_num
result = find_max_num(input)
print(result)

시간복잡도 : 2N == 1안에 비해 효율적.

2. 알파벳별 빈도수 세기

def find_alphabet_occurrence_array(string):
    alphabet_occurrence_array = [0] * 26 #공간 26 차지
    #0으로 26개를 채워놔라
    for char in string :
        if not char.isalpha():
            continue # == char가 alphabet이 아니면, 다음 문자로 넘어가라 == 띄어쓰기는 카운트에서 제외하기 위함.
        arr_index = ord(char) - ord("a") #공간 1 차지
        #ord 함수는 내장함수임. alphabet의 고유 ASCII 번호를 계산해줌. ord("a") = 97, ord("b") = 98... 이런식.
        #즉, ord(char) - ord("a") = 0. 따라서 문자열에 a가 등장하면 0번째 리스트에 카운트를 1씩 올려준다!, 값이 1이면 1번째 리스트에 1씩 올려준다!
        alphabet_occurrence_array[arr_index] += 1 #공간 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] == a는 3번, e는 2번 ... 이라는 뜻!

3. 최대 빈도의 알파벳 찾기

input = "hello my name is sparta"
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','w','x','y','z'] #공간 26 차지
    max_occurrence = 0 #공간 1 차지
    max_alphabet = 0 #공간 1 차지
    for alphabet in alphabet_array : #== for alphabet에서 alphabet은 alphabet_array의 각 요소들 a, b, c, d각각을 의미함.
        occurence = 0 #공간 1 차지
        for a in string : # == a는 받은 값(string = input)의 각 요소 h, e, l, l, o ...를 의미함.
            if a == alphabet:
                occurence += 1
        if occurence > max_occurrence:
            max_alphabet = alphabet
            max_occurrence = occurence
    return max_alphabet
result = find_max_occurred_alphabet(input)
print(result)

결과 = a

4. 숫자 존재여부 판단

#배열 내에서 특정 숫자가 존재한다면 True, 존재하지 앟는다면 False
input = [3, 5, 6, 1, 2, 4]
def is_number_exist(number, array):
    for i in array: #array의 길이만큼 아래 연산이 실행 = N
        if number == i: #비교연산 1회
            return True
    return False
result = is_number_exist(10, input)
print(result)

결과 = Flase

5. 리스트 내 숫자를 더하거나 곱해서 최대값 출력하기

#더하기나 곱하기를 배열 사이에 포함시켜 뽑을 수 있는 최대값은??
#생각해야할 것
# 1. 요소들에 0이나 1을 곱하면 안 되겠다. 더해주는게 숫자를 더 크게하는 것임.
# 2. 즉, 요소가 0, 1이거나 / 현재까지의 합계가 0, 1이면 더해주는게 이득
input = [0, 3, 5, 6, 1, 2, 4]
def find_max_plus_or_multiply(array):
    multifly_sum = 0
    for number in array:
        if number <= 1 or multifly_sum <= 1:
            multifly_sum += number
        else :
            multifly_sum *= number
    return multifly_sum
result = find_max_plus_or_multiply(input)
print(result)

결과 = 728
시간복잡도 = N / Big O 표기법 = O(N)

6. 문자열에서 반복되지 않는 첫번째 문자를 반환하기

def find_not_repeating_character(string):
    alphabet_occurrence_array = [0] * 26
    for char in string:
        if not char.isalpha(): #== 띄어쓰기 무시
            continue
        arr_index = ord(char) - ord("a")  # == ASCII코드 이용/ array 내 고유 공간 식별
        alphabet_occurrence_array[arr_index] += 1  # 공간 1 차지
    alphabet_not_repeating = []
    for index in range(len(alphabet_occurrence_array)):
        alphabet_occurrence = alphabet_occurrence_array[index]
        if alphabet_occurrence == 1:
            alphabet_not_repeating.append(chr(index + ord("a")))
    for char in string:
        if char in alphabet_not_repeating:
            return char
    return alphabet_occurrence_array
result = find_not_repeating_character(input)
print(result)

결과 = c

7. input(숫자)의 소수를 구하기
1안) 시간복잡도 = N^2

input = 20
def find_prime_list_under_number(number):
    prime_list = []
    for n in range(2, number+1):# n <- 2 ~ number+1 / range 함수는 number+1에서 하나를 뺀 숫자인 number까지 반복함! 특성임.
        for i in range(2, n): # i의 범위 : 2부터 n-1까지
            if n % i == 0:
                break
        else:
            prime_list.append(n)
    return prime_list
result = find_prime_list_under_number(20)
print(result)

2안)
2와 3으로 나누어 떨어지지 않는다면, 2 X 3 인 6으로도 당연히 안 나누어 떨어집니다. 즉, 2부터 n-1 까
지 모든 수 로 나누어 떨어지지 않는지 확인하는 것이 아니라, 2부터 n-1 까지 모든 소수 로 나누어 떨어지지 않는지
알아보도록 개선해봅시다.
그러면, 뭐가 소수인지는 어떻게 알 수 있을까요? 바로, 직전에 찾은 소수들을 이용하면 됩니다.

input = 20
def find_prime_list_under_number(number):
	prime_list = []
	for n in range(2, number + 1):
		for i in prime_list:
			if n % i == 0:
				break
		else:
			prime_list.append(n)
	return prime_list
result = find_prime_list_under_number(input)
print(result)

결과 = 2, 3, 5, 7, 11, 13, 17, 19

8. 문자열 뒤집기
문자열 뒤집기! 최소 시도로 모두 1이나 0으로 바꾸려면 몇번 시도해야할까?
모두 0으로 바꾸려면 가운데 1111을 '한번' 뒤집으면 가능.
모두 1로 바꾸려면 앞, 뒤의 0을 각 한번씩 '두번' 뒤집으면 가능
따라서 '한번' 뒤집는게 좋겠다. 숫자 1을 반환해야한다.

input = "011110"
def find_count_to_turn_out_to_all_zero_or_all_one(string):
    count_to_all_zero = 0
    count_to_all_one = 0
    if string[0] == '0': #규칙성 2번! 맨 앞 숫자에 관한 부분임
        count_to_all_one += 1
    elif string[0] == '1':
        count_to_all_zero += 1
    for i in range(len(string)-1): # == range(0,5) == '01111' / 마지막 0 제외. 왜냐하면 if string[i+1] == '1' 조건문 써야해. 만약 len(string)-1 안해주면 range 벗어나서 오류남.
        if string[i] != string[i+1]: # i번째가 그 다음 i와 같지 않다면~~ 0 -> 1 / 1 -> 0 으로 뒤집하는 부분을 의미함.
            if string[i+1] == '0':    # 그 다음 i가 0이라면~
                count_to_all_one += 1
            if string[i+1] == '1':     # 그 다음 i가 1이라면~
                count_to_all_zero += 1
    return min(count_to_all_zero, count_to_all_one)
result = find_count_to_turn_out_to_all_zero_or_all_one(input)
print(result)

결과 = 1

profile

0개의 댓글