2017-10-15 3 views
0

OCaml에서 더 빠른 버전의 지수 함수를 찾는 데 어려움이 있습니다. 여기에 내가 따르려고 몇 가지 지침입니다빠른 지수 함수 만들기

  1. 보다는이 함수는 n은 B 두 개의 인수를 수신 expt b n ==> b * (b * (b ...)의 전형적인 순환 지수 버전은 기본적으로 나누기를 받아 입장을 정복.
  2. n이 홀수 다음 fastexpt b n => b * (b^(n - 1))

가 여기에 지금까지 작성한 코드의 경우 n은 다음, 심지어 다른 fastexpt b n => (b^(n/2))^2 경우 :

let fastexpt : int -> int -> int 
= fun b n -> 
    if n = 0 then 1 
    else if ((n mod 2) = 0) then (expt b (n/2)) * (expt b (n/2)) 
    else b * (expt b (n - 1));; 

내 질문은이 : 작성하는 방법이 있나요 expt 기능을 사용하지 않고이 기능을 사용할 수 있습니까?

+2

사용'? –

+0

아마도 OCaml 언어를 너무 잘 이해하지 못 하겠지만, fastexpt를 포함한다면 fastexpt의 초기 정의를 "let rec"라고해야할까요? – Sean

+1

@Sean, https://stackoverflow.com/help/how-to-ask : ** 질문 게시 및 피드백에 회신 게시 한 후 브라우저에 질문을 약간 열어두고 누군가가 논평하면. 확실한 정보를 놓친 경우 질문을 편집하여 응답 할 준비를하십시오. 누군가가 답변을 게시 할 경우 시험해보고 의견을 제공 할 준비를하십시오! ** 질문을 할 때 답변을 수락하고 의견이나 답변에 응답하십시오. 모든 질문에는 이상한 답변이 없습니다. 무례하게 굴지 마라, 사람들은 도우려고 여기있다. 떠나지 말고 대화하지 마라. – Lhooq

답변

1

당신이

또 다른 것은이 때문이다 (우리는 당신이 이미 expt를 선언 한 것을 고려하는 경우) 계산의 나머지 부분에 대한 일반적인 하나를 사용하여 다음 분할을 사용하는 방법을 처음 정복하고 여기에 일을하는지 n이 홀수 인 경우 b * b^((n-1)/2) * b^((n-1)/2)을 반환 할 수 있습니다. 이는 빠른 지수 계산의 목적입니다.

그냥 재귀로 fastexpt를 정의하고 그것을 모든 방법을 사용할 수 있습니다 어떻게해야하나요 : fastexpt` 대신

let rec fastexpt : int -> int -> int 
= fun b n -> 
    if n = 0 then 1 
    else 
     let b2 = fastexpt b (n/2) in 
     if n mod 2 = 0 then b2 * b2 
     else b * b2 * b2;; 
+3

만약 당신이 빠른 지수를 가지려고한다면, CPU에서 느린 명령어이기 때문에'mod'와 division을 피할 수도 있습니다. 대신에 2의 제곱으로 정수 나누기에 대해 비트 시프트 연산을 사용할 수 있으며 비트 연산을 사용하여 숫자의 패리티를 테스트 할 수 있습니다. 첫 번째 비트가 0으로 설정되면 숫자는 짝수입니다. 그러나 OCaml 컴파일러가 이미 이러한 최적화를 수행하고있을 가능성이 있지만 시도해 볼 필요가 있습니다. –

+0

네, 고맙습니다, 실제로 알고리즘 관점에서 대답했지만 포인트는 주목할 가치가 있습니다. ;-) – Lhooq

+1

@AnthonyScemama 컴파일러는 이러한 최적화를 수행합니다. 당신이 최적을 원한다면, 정수가 계산 중에 박스 화되지 않도록 보장하는 어두운 마법이있을 수 있습니다 (수동으로 수행 할 수 있는지는 확실하지 않지만). – PatJ