백준 문제 푼거 정리 - 문자열 사용하기
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을 출력
생각한 방법
- 단어 입력 받기, a~z까지 담겨있는 문자열 생성
- 이중 포문 돌아서 같으면 그 위치인덱스+1) 출력, 다르면 -1 출력.
Q) 언제 문자열을 쓰고 언제 리스트를 사용할까?
멘토님께 물어보니, 문자열은 길이가 정적이라 할당처리하는 것도 번거롭다. 다른 자료구조들이 리스트 기반이라 확장도 편이해서 리스트를 더 선호한다. 간단한 거라면 문자열 선호.
예를 들어 (사실 a~z까지 타이핑해서 저장하는게 가장 좋을)
# 한 문자열로 저장하는 방법 (a~z까지)
for i in range(ord('a'), ord('z')+1):
a.append(chr(i))
b += chr(i)
Q) 문자열 위치 알려주기
-
a.find(‘b’) a(문자열)에서 b가 처음 나온 위치를 반환 만약 찾는 문자나 문자열이 존재하지 않으면 -1을 반환
-
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 문자열 반복
- 테스트 케이스의 개수만큼 for문 한번 돌고
- 반복횟수를 입력 받고, 리스트에 문자열 구분해서 넣고
- 반복횟수와 리스트를 곱해서 출력.
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 단어공부
알파벳 대소문자로 이루워진 단어가 주어진다. 가장 많이 사용된 알파벳이 여러개이면 ?를 출력, 아니면 가장 많이 사용된 알파벳을 대문자로 출력
※ 대소문자를 가리지 않고 다 똑같은 걸로 취급한다
- 알파벳별로 갯수를 가지는 리스트를 생성한다.
- find를 활용하여 for 문을 한번만 돌리고도 알파벳을 찾는다.
- 대문자와 소문자의 갯수를 따로 찾아서 통합한다.
- 같은 게 있는지 확인하고 출력한다.
-> 문제점. 전체를 문자열로 처리해서 더해버리니까 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