Covenant


0. 무엇을 공부할까요?

파이썬의 정수, 문자열, 배열 자료형에 대해서 살펴볼 것입니다. 파이썬 기본 문법책을 펴보면 가장 앞 단원에 나오기에 자신이 있을텐데요. 코딩테스트를 준비하는 관점에서 재해석하여 백준 예제와 함께 공부해보겠습니다.



1. 정수

1-1. 최대, 최소

ans = ???
for num in arr:
    if ans > num:
        ans = num
print(ans)

배열 arr에 있는 값을 for 문으로 순회하고 있습니다. 마지막에 출력되는 ans에 arr에 저장되어 있는 값 중 최솟값이 저장되게 하고 싶습니다. 그러면 첫번째 줄 ans에 무엇을 저장해야 할까요? arr에 있는 최댓값보다 큰 수가 저장되면 됩니다.

ans = 999999

ans에 임의로 큰 값을 쓰는 방법도 있습니다. 보통은 문제에서 주어지는 입력 범위 값보다 큰 값을 설정합니다. 예를 들어 arr에는 100,000을 넘지 않는 값이 저장된다고 하면 ans = 100,001로 초기화 하면 됩니다. 하지만 최대, 최소 범위를 정하기 애매한 상황에서 우아한 방법은 아래와 같습니다.

import sys 
ans = sys.maxsize

ans 값을 출력하면 큰 값이 출력됩니다. 다만 파이썬은 1편에서 설명한 것 처럼 아무리 큰 정수라도 범위의 제한 없이 연산이 가능합니다. 따라서 sys.maxsize가 저장된 ans라 하더라도 ans += 1 연산이 가능하다는 사실은 참고로 알아주세요.



2. 진법

진법은 입사 코딩테스트에서 빈도가 많이 떨어집니다. 하지만 처음에 연습문제로 풀 백준 브론즈 구현문제에는 왕왕 나오기에 한번 다루고 가겠습니다.


2-1. 10진수 → 2, 8, 16진수 변환

>>> bin(42) 
>'0b101010' 
>>>> oct(42) 
>'0o52' 
>>>> hex(42) 
>'0x2a'

정수값에 bin, oct, hex를 붙이면 각각 2진수, 8진수, 16진수 입니다.



2-2. 2, 8, 16진수 → 10진수 변환

>>> int('0b111100', 2) 
> 60
>>> int('0o74', 8) 
> 60
>>> int('0x3c', 16)
> 60

주어진 2진수, 8진수, 16진수를 10진수로 변환하면 60이 나옵니다.



2-3. 진법 연산 예제

3
1001101 10010
1001001 11001
1000111 1010110

백준 2729번 이진수 덧셈 문제를 요약하면 첫 줄에는 테스트 케이스의 수가 주어지며, 테스트 케이스 줄 수 만큼 2진수가 두 개 주어진다고 했을 때 각 이진수의 합을 구하라는 문제입니다.

for _ in range(int(input())):  
    A, B = map(int, input().split())  
    print(bin(A)+bin(B))

일단 int로 입력받아 bin()로 변환하고 바로 덧셈 연산을 하면 됩니다. 그러면 이진수는 이진수 연산이 이루어집니다. (이진수 덧셈을 구현할 이유는 절대 없습니다.)



2-4. 진법 연습문제

진법에 자신감을 얻기 위해서 다음 문제를 추천합니다.



3. 문자열


3-1. 문자열을 거꾸로

문자열 ABCD를 DCBA로 바꾸는 코드는 다음과 같습니다.

alph = "ABCD"
alph[::-1]

이와 같은 방법으로 백준 10988번 팰린드롬인지 확인하기 문제를 쉽게 풀 수 있습니다.

inputStr = input()
if inputStr == inputStr[::-1]:
    print(1)
else:
    print(0)

▲ 백준 10988번 곱셈 정답 코드

팰린드롬 문자는 앞으로 읽어도, 뒤로 읽어도 같습니다. 따라서 정방향 문자열과, 역방향 문자열을 한글자씩 비교하면 됩니다.


3-2. 문자열 <--> 아스키코드

ord() # 문자를 아스키코드로 변환하는 함수 
chr() # 아스키코드를 문자로 변환하는 함수

기업 코딩테스트에서 아스키코드를 직접 활용하라는 문제의 출제빈도는 낮습니다. 이렇게 내장함수만 알려주고 넘어가긴 썰렁하니 백준 11654번 아스키 코드 문제를 풀어보세요.



4. 배열


4-1. 배열 초기화

배열 초기화는 그래프 문제를 해결할 때 밥먹듯이 사용합니다. 초기화 형태를 기억하셔서 거침없이 사용하기를 바랍니다.

3 5

두 정수가 첫째줄에 입력값으로 들어옵니다. 첫 번째 정수는 배열의 가로 크기를, 두 번째 정수는 배열의 세로 크기인 0으로 초기화된 배열을 만들어봅시다. 위의 입력값은 가로 3, 세로 5인 크기의 배열을 0으로 초기화 해야합니다.

N, M = map(int, input().split())
arr = [[0] * N for _ in range(M)]

여기서 낯선 표현이 등장합니다. for _ in range(M) 보통 for와 in 사이에 i, j, k를 넣지 않았나요? for i in range(M) 이렇게요. 하지만 i의 값을 이용할 필요가 없는 경우 _ 를 사용하기도 합니다.
여기서 팁을 드리면 배열의 가로 세로를 N, M으로 정하면 편합니다. 문제마다 가로와 세로를 M와 N으로 문제와는 반대로 주는 경우가 있는데 여러분들이 딱 N, M을 가로, 세로로 쓴다고 정하면 index out of range 에서 자유로울 수 있습니다.



4-2. 배열의 원소를 거꾸로

arr.reverse()

배열의 원소를 거꾸로 하려면 reverse() 를 사용하면 됩니다. 반환 값이 없으니 이점 유의해주세요. 역시 이렇게 하나만 알려주고 넘어가면 썰렁하니 백준 2588번 곱셈 문제를 풀어봅시다.

472
385

▲ 입력

각 줄에 정수가 입력됩니다. 곱셈시 중간연산의 수를 출력하면 됩니다.

A = int(input())  
B = int(input())
arr_B = [int(i) for i in str(B)]  
arr_B.reverse()  

for i in range(len(arr_B)):  
    print(A * arr_B[i])  
print(A * B)

▲ 백준 2588번 곱셈 정답 코드

네번째줄에 reverse() 를 활용해서 답을 구할 수 있습니다. 세 번째 줄에 arr_B = [int(i) for i in str(B)] 이 부분이 이해가 되산요? B의 값을 문자열로 변환한 다음에 앞에서 한 글자씩 배열에 넣는 코드입니다.

arr = list(map(int, list(String)))  
arr = [int(i) for i in String]

두 코드 모두 arr에 [1, 2, 3]이 저장됩니다.



4-3. 배열 원소 갯수

list.count(찾는 값)

값이 배열에 몇 개가 있는지 찾으려면 위와 같이 쓰면 됩니다.

str.count(찾는 값) 

배열 뿐만 아니라 문자열도 가능합니다.

너무 싱거운가요? 그래서 문제를 준비했습니다. 백준 2490번 윷놀이 문제입니다.

def check(arr):
    num_of_zero = arr.count(0)
    if num_of_zero == 0:
        print("E")
    elif ...

for i in range(3):
    arr = list(map(int, input().split()))
    check(arr)

▲ 백준 2490번 윷놀이 정답 코드 일부

arr에 윷의 정보가 있습니다. 0은 윷의 바닥을 표현합니다. count 를 이용해서 0의 갯수를 구한 간단한 문제입니다.



4-4. 원소 중복 제거

alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'c', 'd' ] 
alpha = list(set(alpha)) 

set은 저장된 원소가 유일합니다. 따라서 배열에 저장된 값이 중복 없이 alpha에 저장됩니다. 여기서 한 단계 더 들어가 볼까요?


lst = [[1,2], [1,2], [1]] 

2차원 리스트가 있습니다. 중복된 값을 제거하려면 어떻게 해야할까요?

print(list(set(map(tuple, lst))))

위와 같이 작성하면 됩니다.



4-5. 배열 정렬

arr.sort()

배열을 오름차순으로 정렬하는 방법은 위와 같습니다.

arr.sort(reverse=True)

배열을 내림차순으로 정렬하는 방법은 위와 같습니다.
배열의 원소가 한 개가 아닌 리스트라면 다음과 같은 방법을 사용합니다.

arr.sort(key=lambda x:(x[0], x[1]))

위의 코드를 바탕으로 백준 11650번 좌표 정렬하기 문제를 해결 할 수 있습니다. N개의 점이 주어지고 각 줄에 x와 y 좌표 정보가 주어집니다. x좌표가 증거하는 순으로 정렬하며, x 좌표가 같으면 y좌표를 기준으로 출력하는 코드를 작성해야합니다.

arr = []
for _ in range(int(input())):
    arr.append(list(map(int, input().split())))

arr.sort(key=lambda x:(x[0], x[1]))

for e in arr:
    print(str(e[0]) + " " + str(e[1]))

▲ 백준 11650 정답코드

arr.sort(key=lambda x:(x[0], x[1])) 를 이용해서 x[0] (x좌표)을 정렬하고, x[0] 값이 같다면 x[1] (y좌표)을 기준으로 오름차순 정렬합니다.


그렇다면 내림차순 정렬을 하는 방법은 무엇일까요? -x[0] 이렇게 -를 붙이면 됩니다. 이 방법을 이용하면 백준 10825번 국영수 문제를 해결할 수 있습니다.

arr.sort(key = lambda x : (-x[1], x[2], -x[3], x[0]))

▲ 백준 10825번 국영수 정답 코드 일부

덤~

파이썬에는 삼항 연산자를 다음과 같이 사용합니다.

[True 조건] if 조건 else [False 조건]

a와 b 중에서 큰 값을 res(result의 약자)에 저장한다고 합시다.

if a > b:
    res = a
else:
    res = b

혹시 이렇게 코드를 작성하나요? 우하한 방법으로 다음과 같이 써주세요!

res = a if a > b else b






광고 꽝고~