2014-09-17 4 views
0

У меня есть следующая функция, чтобы проверить, является ли положительное значение четным.Значение проверки схемы, если даже не

(define (even? n) 
    (cond 
     ((= n 0) #t) 
     ((< n 0) #f) 
     (else (even? (- n 2))) 
    ) 
) 

Я пытаюсь использовать эту функцию для увеличения магазина счетчика, когда проверяются значение не четное (нечетное), используя как even? функции и логическую not, но я не могу показаться, чтобы выяснить, правильно синтаксис.

(define (function a b) 
    (define (iter a b store) 
     (cond 
      ((= b 1) (+ store a) 
      (else 
       (iter (double a) (halve b) (if (not (even? b)) (+ a store) store))) 
      ) 
     ) 
    (iter a b 0) 
) 

Может ли кто-нибудь проверить мой синтаксис, чтобы увидеть, что я делаю неправильно?

Вызов (function 1 1) должен возвращать 1

Вызов (fucntion 1960 56) должен возвращать 109760, но я получаю 141120

EDIT: Я понимаю, что мой halve Funciton должен быть impromperly определен. Я попытался реализовать функцию сокращения пополам, которая использовала только вычитание.

(define (halve n) 
    (define (iter src store) 
     (cond 
      ((<= src 0) store) 
      (else (iter (- src 2) (+ store 1))) 
      ) 
     ) 
    (iter n 0) 
    ) 
+0

Ваш первый случай в 'iter' возвращает' store', если 'b' равно 1 (что в вашем примере оно), поэтому оно возвращает 0; вы даже не добираетесь до использования 'even?'. –

+0

@ScottHunter Я обновил базовый футляр, потому что вы были правы. Тем не менее, я все еще получаю проблемы с большими номерами. – user3277752

ответ

1

Обратите внимание, что функция even? встроена, вам не нужно ее реализовывать. Теперь по поводу проблемы - это линия не делает то, что вы думаете:

(if (not (even? b)) (+ a store)) 

Это выражение не обновляет значение store, это просто оценить результат добавления a к store, а затем полученное значение теряется - мы не сохранили его, мы не передали его рекурсии, результат добавления отбрасывается, а затем выполняется следующая строка.

В схеме мы используем set! для обновления переменной, но на нее нахмурились, мы стараемся избегать операций мутации - и в этом случае это необязательно, нам нужно передать правильное значение рекурсивному вызову.

UPDATE

Теперь, когда вы дали понять, что вы реализуете алгоритм Ethiopian multiplication, это то, как это должно быть сделано:

(define (halve n) 
    (quotient n 2)) 

(define (double n) 
    (* 2 n)) 

(define (function a b) 
    (define (iter a b store) 
    (cond 
     ((= a 0) store) 
     ((even? a) (iter (halve a) (double b) store)) 
     (else (iter (halve a) (double b) (+ store b))))) 
    (iter a b 0)) 

Он работает, как ожидалось:

(function 1 1) 
=> 1 
(function 1960 56) 
=> 109760 
+0

Это лучше. Базовый блок теперь работает так, как ожидалось, но для второго случая я все еще не возвращаю правильный номер. – user3277752

+1

@ user3277752 будет намного проще, если вы сообщите нам фактическое имя и определение функции, его нельзя назвать просто «функцией». Кроме того, пожалуйста, не обновляйте вопрос нашими решениями, это приведет к аннулированию предыдущих ответов. –

+0

Я пытаюсь реализовать эфиопское умножение. Когда я печатаю это, я понял, что моя проблема «половина» должна быть проблемой. – user3277752

1

Вы, кажется, отсутствует ), как раз перед вызовом iter.

+1

Теперь должно быть правильно, но я не думаю, что это причина, по которой он не работает. – user3277752

Смежные вопросы