no image
[백준 1978번 문제, 파이썬3] 소수 찾기
문제 문제 주어진 수 N개 중에서 소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오. 입력 첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다. 출력 주어진 수들 중 소수의 개수를 출력한다. 코드 count = int(input()) numbers = list(map(int, input().split())) answer = 0 for i in numbers: div_count = 0 for j in range(1, i+1): if i % j == 0: div_count += 1 if div_count == 2: answer += 1 print(answer) 해결 생각 참고 링크
2023.05.20
no image
파이참 PyCharm 에서 pypy3 인터프리터 설정하는 방법
pypy3란? 바드 선생님의 답변 PyPy는 Python 코드를 해석하고 실행할 수 있는 가상 머신입니다. Python 인터프리터보다 빠르도록 설계되었으며 일부 Python 코드에서 CPython보다 2~3배 빠를 수 있습니다. PyPy는 JIT(Just-In-Time) 컴파일러를 사용하여 Python 코드를 기계어로 컴파일하여 속도를 향상시킵니다. 또한 PyPy는 Python 코드를 최적화하는 데 사용할 수 있는 다양한 기능을 제공합니다. Python과 PyPy의 주요 차이점은 PyPy는 Python 코드를 JIT 컴파일하는 반면 Python은 Python 코드를 해석한다는 것입니다. JIT 컴파일은 프로그램 실행 시점에 Python 코드를 기계어로 번역하는 프로세스입니다. 이렇게 하면 Python 코..
2023.05.20
no image
[백준 10828번 문제, 파이썬3] 스택
문제 문제 정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오. 명령은 총 다섯 가지이다. push X: 정수 X를 스택에 넣는 연산이다. pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다. size: 스택에 들어있는 정수의 개수를 출력한다. empty: 스택이 비어있으면 1, 아니면 0을 출력한다. top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다. 입력 첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,0..
2023.05.19
no image
[백준 2386번 문제, 파이썬3] 도비의 영어 공부
문제 문제 꿍은 도비의 자유를 위해 영어를 가르치기로 결심했다. 하지만 도비는 바보라 ABC부터 배워야 한다. 그래서 꿍은 영어 문장과 알파벳 하나가 주어지면 그 알파벳이 문장에서 몇 번 나타나는지를 세는 문제들을 내주었다. 하지만 도비는 마법사고 컴공도 마법사다. 여러분은 도비를 위해 문제의 답을 알려주는 프로그램을 만들수 있을것이다! 입력 입력은 몇 개의 줄들로 이루어진다. 각 줄에는 하나의 소문자와 영어 문장이 공백으로 구분되어 주어진다. 각 문장은 길이가 1에서 250이며 입력의 마지막은 #이다. 출력 출력의 각 줄은 입력으로 주어진 소문자와 그 소문자 알파벳이 나타난 횟수로 이루어진다. 이때 문장에서 해당 알파벳이 소문자로 나타나던 대문자로 나타나던 모두 세야 한다. 코드 import sys w..
2023.05.19
no image
캡스톤 디자인 앱 만들기 My Walking Pet #0
전부터 만들고 있던 캡디 My Walking Pet 개발 일지를 써보려고 합니다 MpChart 의 BarChart의 스와이프 리스너를 사용하려면 부득이하게 차트의 드래그 가능 플래그를 꺼야했습니다. https://github.com/PhilJay/MPAndroidChart/issues/405 Fling Gesture Not Recognized if Max Visible X range is set. · Issue #405 · PhilJay/MPAndroidChart Hello. I'm trying to implement an update based on a Fling gesture, where new values are added to the graph as the user swipes left and r..
2023.05.19
no image
[백준 1654번 문제, 파이썬3] 랜선 자르기
문제 코드 이분 탐색으로 작성된 코드 import sys k, n = map(int, sys.stdin.readline().split()) lan_list = sorted([int(sys.stdin.readline()) for _ in range(k)]) max_len = max(lan_list) min_len = 1 answer = 0 while min_len = n: answer = mid_len min_len = mid_len + 1 else: max_len = mid_len - 1 print(answer) 시간초과 나온 코드 import sys k, n = map(int, sys.stdin.readline().split()) lan_list = [int(sys.stdin.readline()) fo..
2023.05.19
no image
[백준 2751번 문제, 파이썬3] 수 정렬하기 2
문제 https://www.acmicpc.net/problem/2751 2751번: 수 정렬하기 2 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다. www.acmicpc.net 문제 N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오. 입력 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다. 출력 첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다. 코드 일반적..
2023.05.19
no image
[백준 15829번 문제, 파이썬3] Hashing
문제 https://www.acmicpc.net/problem/15829 15829번: Hashing APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정 www.acmicpc.net 문제 APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정의한다. 해시 함수는 무궁무진한 응용 분야를 갖는데, 대표적으로 자료의 저장과 탐색에 쓰인다. 이 문제에서는 여러분이 앞으로 유용하게 쓸 수 있는 해시 함수를 하나 가르쳐주고자 한다. 먼저, 편의상 ..
2023.05.19
728x90
반응형

문제

문제

주어진 수 N개 중에서 소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오.

입력

첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.

출력

주어진 수들 중 소수의 개수를 출력한다.


코드

count = int(input())
numbers = list(map(int, input().split()))

answer = 0
for i in numbers:
    div_count = 0
    for j in range(1, i+1):
        if i % j == 0:
            div_count += 1

    if div_count == 2:
        answer += 1

print(answer)

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

pypy3란?

바드 선생님의 답변

PyPy는 Python 코드를 해석하고 실행할 수 있는 가상 머신입니다. Python 인터프리터보다 빠르도록 설계되었으며 일부 Python 코드에서 CPython보다 2~3배 빠를 수 있습니다. PyPy는 JIT(Just-In-Time) 컴파일러를 사용하여 Python 코드를 기계어로 컴파일하여 속도를 향상시킵니다. 또한 PyPy는 Python 코드를 최적화하는 데 사용할 수 있는 다양한 기능을 제공합니다.

Python과 PyPy의 주요 차이점은 PyPy는 Python 코드를 JIT 컴파일하는 반면 Python은 Python 코드를 해석한다는 것입니다. JIT 컴파일은 프로그램 실행 시점에 Python 코드를 기계어로 번역하는 프로세스입니다.

이렇게 하면 Python 코드를 해석하는 데 필요한 시간과 리소스를 절약할 수 있습니다.PyPy는 Python 인터프리터보다 빠르도록 설계되었지만 Python 인터프리터보다 메모리 집약적일 수도 있습니다. 특정 응용 프로그램에 가장 적합한 구현은 구현의 속도, 메모리 사용량 및 기타 요인에 따라 달라집니다.

 

pycharm은 파이썬언어로 코딩할 수 있는 ide입니다. 프로젝트를 생성할 때 인터프리터를 설정할 수 있는데

pypy3를 설치해서 인터프리터를 연결하면 파이참에서 pypy3로 코딩할 수 있습니다. 그렇다곤 하지만 python과 pypy의 

언어 문법은 같다고 하기 때문에 별 차이는 없겠지만 그래도 해봅시다!

 

pypy3 설치

https://www.pypy.org/

 

PyPy

A fast, compliant alternative implementation of Python Download PyPy What is PyPy ? Documentation (external link) On average, PyPy is 4.8 times faster than CPython 3.7 PyPy (with JIT)

www.pypy.org

 

위 사이트에 들어가서 Donwload PyPy 를 클릭해줍시다.

깨알같이 밑에 원래 python 보다 4.8배 빠르다고 적혀있네요.. 그런데 백준 풀때 어떤 문제는 더 느리던데 ㅎㅎ..

 

 

아무튼 다운로드 버튼을 누르면 pypy 버전별 다운로드하는 사이트로 들어와집니다. 여기서 운영체제랑 버전별로 설치할 수 있는데, 저는 Windows 64 bit PyPy3.9 버전으로 다운로드하겠습니다.

 

 

다운로드한 압축파일을 c 풀더에 아무이름으로 풀더를 만들어서 가져왔습니다. 가능하면 풀더 경로에 한글이 들어가지 않도록 만들어주세요. 저처럼 c드라이브 풀더에 pypy 풀더를 만들어서 가져다 놓으셔도 됩니다. 

 

이제 압축을 풀어줍시다.

 

 

압축을 풀고 만들어진 풀더로 들어가면 이렇게 pypy 파일들이 들어있는걸 보실 수 있습니다. 여기서 pypy 3.9.exe 파일을 실행해볼까요? 

 

 

그러면 보통은 pc 보호 이렇게 뜰텐데 관리자 모드로 실행하셔도 되고 추가정보 누르고 실행 누르셔도 됩니다

 

 

그러면 익숙한 파이썬 파일과 비슷하게 나옵니다.

 

 

파이썬 문법을 그대로 사용할 수 있습니다.

 

이제 사용자 설정 변수 창을 열어서 환경변수로 등록해줍시다.

 

 

윈도우 키 눌러서 "환경" 이라고 검색하면 시스템 환경 변수 편집 바로가기가 나옵니다.

 

 

맨 밑에 환경 변수 버튼 클릭

 

 

시스템 변수 혹은 사용자이름에 대한 사용자 변수 여기 아무 곳에 Path 를 찾아서 편집을 눌러줍시다

 

 

그리고 pypy 파일들이 있는 경로를 복사합니다.

 

 

새로 만들기 클릭 -> 복붙 

 

 

그리고 확인 눌러줍시다

 

환경 변수가 제대로 등록되었는지 확인하기 위해

윈도우 키 + r -> cmd 클릭 후 확인 

 

 

 

pypy -v 입력했을 때 뭔가 막뜨면 제대로 된겁니다.

 

이제 pycharm으로 갑시다

 

PyCharm 에서 pypy3 인터프리터 설정하기

 

 

파이참 -> 파일 -> 새 프로젝트 클릭

 

 

환경변수가 제대로 등록되었으면 기본 인터프리터 리스트 박스를 클릭하면 pypy 인터프리터가 나옵니다.

 

 

pypy.exe로 눌러줍시다.

안나온다면 직접 경로를 설정하셔야하고 ... 버튼을 클릭해서 pypy.exe 클릭해주시면됩니다.

 

그리고 생성

 

 

그러면 pypy 인터프리터로 프로젝트가 생성되었으며

파이썬 언어 문법과 동일하게 코딩하실 수 있습니다!

 

 

실행도 잘 나오는걸 확인하실 수 있습니다.

 

 

728x90
반응형
728x90
반응형

문제

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

  • push X: 정수 X를 스택에 넣는 연산이다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 스택에 들어있는 정수의 개수를 출력한다.
  • empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
  • top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.


코드

import sys

stack = []


def push(i: int):
    stack.append(i)


def pop():
    if empty() == 1:
        return -1

    v = stack[-1]
    del stack[-1]
    return v


def size():
    return len(stack)


def empty():
    if size() == 0:
        return 1
    else:
        return 0


def top():
    if empty() == 1:
        return -1

    return stack[-1]


count = int(sys.stdin.readline().rstrip())

for i in range(count):
    line = list(map(str, sys.stdin.readline().split()))

    command = line[0]
    if command == 'push':
        push(int(line[1]))

    elif command == 'pop':
        print(pop())

    elif command == 'top':
        print(top())

    elif command == 'size':
        print(size())

    elif command == 'empty':
        print(empty())

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

문제

꿍은 도비의 자유를 위해 영어를 가르치기로 결심했다. 하지만 도비는 바보라 ABC부터 배워야 한다.

그래서 꿍은 영어 문장과 알파벳 하나가 주어지면 그 알파벳이 문장에서 몇 번 나타나는지를 세는 문제들을 내주었다. 하지만 도비는 마법사고 컴공도 마법사다.

여러분은 도비를 위해 문제의 답을 알려주는 프로그램을 만들수 있을것이다!

입력

입력은 몇 개의 줄들로 이루어진다.

각 줄에는 하나의 소문자와 영어 문장이 공백으로 구분되어 주어진다.

각 문장은 길이가 1에서 250이며 입력의 마지막은 #이다.

출력

 

출력의 각 줄은 입력으로 주어진 소문자와 그 소문자 알파벳이 나타난 횟수로 이루어진다. 이때 문장에서 해당 알파벳이 소문자로 나타나던 대문자로 나타나던 모두 세야 한다.


코드

import sys

while True:
    line = sys.stdin.readline().rstrip()
    if line == '#':
        break

    alphabet = line[0]
    line = str.lower(line[2:])
    print(alphabet, line.count(alphabet))

해결

생각


참고

링크

 

 

 

728x90
반응형
728x90
반응형

전부터 만들고 있던 캡디 My Walking Pet 개발 일지를 써보려고 합니다

 

MpChart 의 BarChart의 스와이프 리스너를 사용하려면 부득이하게 차트의 드래그 가능 플래그를 꺼야했습니다.

 

https://github.com/PhilJay/MPAndroidChart/issues/405

 

Fling Gesture Not Recognized if Max Visible X range is set. · Issue #405 · PhilJay/MPAndroidChart

Hello. I'm trying to implement an update based on a Fling gesture, where new values are added to the graph as the user swipes left and right. However, onFling is not called back when a max visible ...

github.com

 

라이브러리 제작자가 무슨 의도인지는 모르겠지만 드래그가 가능할경우 스와이프를 동작하지 않도록 만들어서

본래 자바 코드에 if 구문만 없애면 된다고 하네요. 그렇다고 해도 읽기 전용 모드 이런거 때문에 수정도 못하고

이걸 복붙해서 새로 만들자니 다른것도 또 만들어야하고 어떻게하는지 몰라서 그냥 드래그를 꺼야했습니다.

 

 

그렇게 해서 드래그 애니메이션은 없어졌지만 원래 의도했던대로 스와이프할 때

바 데이터들이 7개씩 넘어가는걸 구현했습니다.

 

지난주부터 걸음 통계 부분을 업데이트 하고 있는데 주간 통계를 어떻게 해야할지 고민이 있었습니다

일요일 ~ 월요일 이렇게 통계를 내거나 그냥 유저가 처음 시작한 날로부터 7일 통계를 내거나

 

가장 간단한건 시작한 날부터 7개씩 끊어서 주간 통계를 내는거였습니다

.

그런데 이것마저도 쉽지는 않더군요... 실제 데이터 사이의 공백이 있을 때 더미데이터를 넣어서 7개를 맞춰주는

방식으로 7개씩 나오도록 만드는데 여기서 1차 막힘 어찌하다 만들어지니까 mpchart를 7개씩 어떻게 넘겨야할지

그거에서 막혔는데 그래도 오늘 차트를 스와이프 하면 7개씩 넘어가면서 보여지는 값들에 평균을 나타내는것까지 할 수 있어서 다행인거같습니다

 

 

넘길 때 애니메이션을 넣으면 좋겠는데 이부분은 전혀 모르니까 답답하기만 하네요. 다음에 시간 나면 일 ~ 월 이렇게 잘라서 7개씩 보여줄 수 있도록 만들어봐야겠습니다. 

 

일단 우선적으로 해야할건 1달 통계와 1년 통계인데 그래프나 BarChart로 보여주자니 힘들어서 못하겠고 다른 방법을 찾아봐야겠습니다. 

 

MpChart BarChart를 드래그 해서 7개씩 넘기는 코드입니다.

 

 

OnChartGestureListener를 구현하는 클래스를 만들어서 차트를 스와이프 할 때 호출되는 메서드를 정의하면됩니다.

 

 

다음에 업데이트때 일지를 또 써야겠습니다

 

 

 

 

728x90
반응형
728x90
반응형

문제


코드

 

이분 탐색으로 작성된 코드

import sys

k, n = map(int, sys.stdin.readline().split())
lan_list = sorted([int(sys.stdin.readline()) for _ in range(k)])

max_len = max(lan_list)
min_len = 1

answer = 0

while min_len <= max_len:
    mid_len = (max_len + min_len) // 2
    count = sum([lan // mid_len for lan in lan_list])

    if count >= n:
        answer = mid_len
        min_len = mid_len + 1

    else:
        max_len = mid_len - 1

print(answer)

 

시간초과 나온 코드

import sys

k, n = map(int, sys.stdin.readline().split())
lan_list = [int(sys.stdin.readline()) for _ in range(k)]
div = sum(lan_list) / n

while True:
    div_list = [int(i / div) for i in lan_list]
    if sum(div_list) != n:
        div -= 1
    else:
        break

print(int(div))

해결

랜선의 길이를 담은 리스트를 만들고 리스트의 최댓값을 구한다.

최솟값은 1

 

최댓값과 최솟값의 중간값을 구하고 해당 값을 기준으로 랜선을 잘라서 만들 수 있는 개수를 구한다.

중간값을 각각의 랜선에 나누면 값이 나오는데 이걸 전부 더하면 몇개가 만들어지는지 알 수 있다.

 

이렇게 더해진 값이 n보다 크면 answer에 저장하고 최솟값을 중간값에 1을 더한 값으로 변경한다

n보다 작으면 최댓값을 중간값에 1을 빼서 변경한다

 

이러한 반복을 최솟값이 최댓값보다 작거나 같을 때 까지 반복해서 최종적으로 answer를 반환하면 된다

 


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

https://www.acmicpc.net/problem/2751

 

2751번: 수 정렬하기 2

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

출력

첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.


코드

일반적인 파이썬 정렬 코드이다

import sys
count = int(sys.stdin.readline())
my_list = [int(sys.stdin.readline()) for _ in range(count)]
for i in sorted(my_list):
    print(i)

해결

음.. 뭔가 이상하다

 

처음 맞췄던 방법은 출제자가 의도한 방법이 아닌것 같아서 병합정렬이랑 계수정렬을 사용해서 코드를 작성했는데

틀렸거나 시간초과 결과가 나온다... 이상하다 

 

병합정렬

import sys


def mergeSort(A, p: int, r: int):
    if p < r:
        q = (p + r) // 2
        mergeSort(A, p, q)
        mergeSort(A, q + 1, r)
        merge(A, p, q, r)


def merge(A, p: int, q: int, r: int):
    i = p
    j = q + 1
    t = 0
    tmp = [0 for i in range(len(A))]
    while i <= q and j <= r:
        if A[i] <= A[j]:
            tmp[t] = A[i]
            i += 1
        else:
            tmp[t] = A[j]
            j += 1
        t += 1
    while i <= q:
        tmp[t] = A[i]
        i += 1
        t += 1
    while j <= r:
        tmp[t] = A[j]
        j += 1
        t += 1
    i = p
    t = 0
    while i <= r:
        A[i] = tmp[t]
        i += 1
        t += 1


count = int(sys.stdin.readline())
my_list = [int(sys.stdin.readline()) for _ in range(count)]
mergeSort(my_list, 0, len(my_list) - 1)
for i in my_list:
    print(i)

 

계수정렬

import sys


# 계수 정렬
def counting_sort(A: list):
    k = max(A)
    c = [0 for _ in range(k + 1)]
    for j in range(len(A)):
        c[A[j]] += 1
    for i in range(1, k + 1):
        c[i] += c[i - 1]
    b = [0 for _ in range(len(A))]
    for j in range(len(A) - 1, -1, -1):
        b[c[A[j]] - 1] = A[j]
        c[A[j]] -= 1
    return b


count = int(sys.stdin.readline())
my_list = [int(sys.stdin.readline()) for _ in range(count)]
for i in counting_sort(my_list):
    print(i)

 

그런데 왜 다 틀렸다고 뜨는거지... 이유를 알수가 없구만


참고

링크

 

 

 

728x90
반응형
728x90
반응형

문제

https://www.acmicpc.net/problem/15829

 

15829번: Hashing

APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정

www.acmicpc.net

문제

APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정의한다. 해시 함수는 무궁무진한 응용 분야를 갖는데, 대표적으로 자료의 저장과 탐색에 쓰인다.

이 문제에서는 여러분이 앞으로 유용하게 쓸 수 있는 해시 함수를 하나 가르쳐주고자 한다. 먼저, 편의상 입력으로 들어오는 문자열에는 영문 소문자(a, b, ..., z)로만 구성되어있다고 가정하자. 영어에는 총 26개의 알파벳이 존재하므로 a에는 1, b에는 2, c에는 3, ..., z에는 26으로 고유한 번호를 부여할 수 있다. 결과적으로 우리는 하나의 문자열을 수열로 변환할 수 있다. 예를 들어서 문자열 "abba"은 수열 1, 2, 2, 1로 나타낼 수 있다.

해시 값을 계산하기 위해서 우리는 문자열 혹은 수열을 하나의 정수로 치환하려고 한다. 간단하게는 수열의 값을 모두 더할 수도 있다. 해시 함수의 정의에서 유한한 범위의 출력을 가져야 한다고 했으니까 적당히 큰 수 M으로 나눠주자. 짜잔! 해시 함수가 완성되었다. 이를 수식으로 표현하면 아래와 같다.

 �=∑�=0�−1��mod�

해시 함수의 입력으로 들어올 수 있는 문자열의 종류는 무한하지만 출력 범위는 정해져있다. 다들 비둘기 집의 원리에 대해서는 한 번쯤 들어봤을 것이다. 그 원리에 의하면 서로 다른 문자열이더라도 동일한 해시 값을 가질 수 있다. 이를 해시 충돌이라고 하는데, 좋은 해시 함수는 최대한 충돌이 적게 일어나야 한다. 위에서 정의한 해시 함수는 알파벳의 순서만 바꿔도 충돌이 일어나기 때문에 나쁜 해시 함수이다. 그러니까 조금 더 개선해보자.

어떻게 하면 순서가 달라졌을때 출력값도 달라지게 할 수 있을까? 머리를 굴리면 수열의 각 항마다 고유한 계수를 부여하면 된다는 아이디어를 생각해볼 수 있다. 가장 대표적인 방법은 항의 번호에 해당하는 만큼 특정한 숫자를 거듭제곱해서 곱해준 다음 더하는 것이 있다. 이를 수식으로 표현하면 아래와 같다.

 �=∑�=0�−1����mod�

보통 r과 M은 서로소인 숫자로 정하는 것이 일반적이다. 우리가 직접 정하라고 하면 힘들테니까 r의 값은 26보다 큰 소수인 31로 하고 M의 값은 1234567891(놀랍게도 소수이다!!)로 하자.

이제 여러분이 할 일은 위 식을 통해 주어진 문자열의 해시 값을 계산하는 것이다. 그리고 이 함수는 간단해 보여도 자주 쓰이니까 기억해뒀다가 잘 써먹도록 하자.

입력

첫 줄에는 문자열의 길이 L이 들어온다. 둘째 줄에는 영문 소문자로만 이루어진 문자열이 들어온다.

입력으로 주어지는 문자열은 모두 알파벳 소문자로만 구성되어 있다.

출력

문제에서 주어진 해시함수와 입력으로 주어진 문자열을 사용해 계산한 해시 값을 정수로 출력한다.


코드

length = int(input())
line = input()

total = [(ord(line[i]) - 96) * 31 ** i for i in range(length)]  # 수열의 합 연산
result = sum(total) % 1234567891  # 나머지 연산

print(result)

해결

문제에서 해싱하는 식을 주기 때문에 문제를 잘 읽고 해싱 공식만 파이썬 코드로 만들면 된다


참고

링크

 

 

 

728x90
반응형