SW 마에스트로 준비(5)

백준 문제 푼거 정리 - 문자열 사용하기

11654 아스키코드

print(ord(r1())) 이렇게 입력하니

TypeError: ord() expected a character, but string of length 2 found 이런 오류가 발생한다. character를 예상하는데, 길이가 2개인 string이 들어왔다는 거자. 나는 A를 입력했기에 A와 \n, 즉 2개가 들어간 것이다. 그래서

print(ord(r1.rstrip())) 이렇게 입력해주니 문제가 해결되었다.

print(ord(input()))은 문제없이 진행되는 것을 보아 마지막 널문자가 안들어가나보다.

10809번 알파벳 찾기

단어를 입력 받아 어떤 알파벳이 포함되어 있다면 그 알파벳이 처음 등장하는 위치를 출력, 포함되어 있지 않다면 -1을 출력

생각한 방법

  1. 단어 입력 받기, a~z까지 담겨있는 문자열 생성
  2. 이중 포문 돌아서 같으면 그 위치인덱스+1) 출력, 다르면 -1 출력.

Q) 언제 문자열을 쓰고 언제 리스트를 사용할까?

멘토님께 물어보니, 문자열은 길이가 정적이라 할당처리하는 것도 번거롭다. 다른 자료구조들이 리스트 기반이라 확장도 편이해서 리스트를 더 선호한다. 간단한 거라면 문자열 선호.

예를 들어 (사실 a~z까지 타이핑해서 저장하는게 가장 좋을)

# 한 문자열로 저장하는 방법 (a~z까지)
for i in range(ord('a'), ord('z')+1):
    a.append(chr(i))
    b += chr(i)

Q) 문자열 위치 알려주기

  1. a.find(‘b’) a(문자열)에서 b가 처음 나온 위치를 반환 만약 찾는 문자나 문자열이 존재하지 않으면 -1을 반환

  2. a.index(‘b’) find와 차이점은 찾는 문자가 없으면 오류 발생

=> find 함수를 쓰면 이중 포문을 돌 필요도 없네

import sys

def rl(): return sys.stdin.readline()

alps = rl()
a = []
for i in range(ord('a'), ord('z')+1):
    print(alps.find(chr(i)), end=" ")

2675 문자열 반복

  1. 테스트 케이스의 개수만큼 for문 한번 돌고
  2. 반복횟수를 입력 받고, 리스트에 문자열 구분해서 넣고
  3. 반복횟수와 리스트를 곱해서 출력.
import sys


def rl(): return sys.stdin.readline()


N = int(rl())

for i in range(N):
    a, b = rl().split()
    str = ""
    for j in b:
        str += j*int(a)
    print(str)

1157 단어공부

알파벳 대소문자로 이루워진 단어가 주어진다. 가장 많이 사용된 알파벳이 여러개이면 ?를 출력, 아니면 가장 많이 사용된 알파벳을 대문자로 출력

※ 대소문자를 가리지 않고 다 똑같은 걸로 취급한다

  1. 알파벳별로 갯수를 가지는 리스트를 생성한다.
  2. find를 활용하여 for 문을 한번만 돌리고도 알파벳을 찾는다.
  3. 대문자와 소문자의 갯수를 따로 찾아서 통합한다.
  4. 같은 게 있는지 확인하고 출력한다.

-> 문제점. 전체를 문자열로 처리해서 더해버리니까 10의자리로 넘어가면 문제가 발생한다. 따라서 리스트로 처리하는게 더 편할 것 같다.

import sys


def rl(): return sys.stdin.readline()


word = rl()

small = []  # 소문자
big = []  # 대문자
total = []  # 전체합

for i in range(ord('a'), ord('z')+1):
    small += str(word.count(chr(i)))

for i in range(ord('A'), ord('Z')+1):
    big += str(word.count(chr(i)))


# 더해서 int형으로 만들기
for i in range(len(small)):
    total.append(int(small[i])+int(big[i]))

# total의 요소들 중 가장 큰 값 반환

# 중복검사
if(total.count(max(total)) > 1):
    print('?')
else:
    print(chr(ord('A')+total.index(max(total))))

-> 위 코드의 문제점 : 답을 다 구한 줄 알았으나 문자열의 길이는 최대 1,000,000인데 배열의 자료형이 char형이므로 127개가 넘으면 overflow가 일어난다. 따라서 int형으로 바꿔서 해야한다.

※ string.ascii_letters, string.ascii_lowercase, string.ascii_uppercase

string library를 쓰면 ascii_lowercase를 통해 소문자를 간단히 생성할 수 있다.

import sys
from string import ascii_lowercase


def r1(): return sys.stdin.readline()


l = list(ascii_lowercase)  # 출력할 소문자

a = r1().lower() ## 입력받자마자 소문자로 바꿔주면, 계산하기 편리하다.
b = []

for i in range(len(l)):  # 알파벳 숫자만큼 돌면서
    b.append(a.count(l[i]))  # 문자의 갯수를 반환한다. 갯수가 없으면 0 반환
print(b)
# max 함수는 반복가능한 자료형을 받아서 가장 큰 요소의 갯수를 출력해준다.
if b.count(max(b)) > 1:  # 문자의 갯수들이 b에 담겨있으므로, 가장 큰 요소의 갯수가 1이상이면, 즉 최대 갯수가 중복되는게 있다면
    print("?")
else:
    print(l[b.index(max(b))].upper())  # index 함수는 리스트x에 있는 x의 위치값을 반환한다.
    # 위치를 반환해서 b에서 입력하고 이를 대문자로 바꿔서 출력하면 문제가 해결된다.


배운 것 -> 입력하자마자 소문자로 바꿔주면 훨씬 수월하게 계산이 가능하다.


참고자료

10809 아스키코드 포문 돌리기 stackoverflow 참고 https://stackoverflow.com/questions/3190122/python-how-to-print-range-a-z

리스트에서 최대값 찾기 : https://ngee.tistory.com/877

1157 단어공부 백준 필독 https://www.acmicpc.net/board/view/30509

1157 참고 https://gomguard.tistory.com/58

0%