mod b를 계산하려면 결과가 b보다 작을 때까지 a에서 b의 배수를 빼야합니다. 간단하게하기 위해 a> = 0, b> 0이라고 가정하겠습니다.하지만 mod-a, b = mod (a, -b) = -mod (a, b) 서명 한 사례.
mod
을 구현하는 가장 순진 (하지만 비효율적 인) 방법은 이것이다 :
def mod(a, b):
while a >= b:
a -= b
return a
a가 b보다 훨씬 큰 경우이 끔찍한입니다. 복잡도는 최악의 경우 O (2^n) 인 O (a/b)입니다. 여기서 n은 비트 수입니다. 대신, 우리는 b의 큰 배수를 뺄 수 있습니다. 우리는 이것을 비트 이동으로 할 수 있습니다.
def mod(a, b):
bs = b
while bs <= a:
bs <<= 1
while bs > b:
bs >>= 1
if a >= bs: a -= bs
return a
이 코드에서, 우리는 변수 b에서 b가 a보다 커질 때까지 왼쪽으로 계속 이동합니다. 한 번에 한 걸음 씩, 우리는 그것을 b로 되돌려 놓고, 가능한 경우 a에서 값을 뺍니다. 이것은 본질적으로 바이너리로 긴 나누기 구현입니다.
시간 복잡도는 다음과 같습니다. 왼쪽 시프트는 O (n)입니다 (여기서 n은 비트 수입니다. 임의의 큰 숫자를 처리한다고 가정). 비교 및 뺄셈입니다. 따라서이 구현에서 두 루프 모두 while
이 필요에 따라 O (n^2)가됩니다.
'modulus'를 구현하라는 질문 만 할 수 있습니다. –
이것은 나에게별로 의미가 없습니다. 정의되지 않은 함수'modulus (x, y)'의 두 계산에 의해'a mod b '의 계산을 대신 할 수 있습니다. 이 함수를 정의하지 않으면 재 작성이 도움이되지 않습니다. (그리고 'modulus'를 정의하더라도 재 작성은 불필요 할 것입니다.) – Gassa
음, 첫 번째 줄은 함수 이름이 될 수 있고 세 번째 줄은 그 함수의 재귀 호출이 될 수 있습니다. 그런 다음 코드는 (GCD (a, b)를 계산하기위한 것이기는하지만) b를 모듈화하지는 않지만 약간의 의미를 갖지만, 너무 느립니다. 예를 들어 a = 1000000000 및 b = 1을 고려하십시오. – Gassa