В Схеме мы пытаемся написать процедуры, используя парадигму функционального программирования . В вашем примере определение счетчика за пределами не является хорошей идеей, чтобы изменить его значение, вам нужно мутировать внутри, используя инструкцию set!
, и мы должныизбегайте именно этого.
Обычное решение (если мы собираемся решить это «вручную») состоит в том, чтобы рекурсивно обходить список и увеличивать значение при каждом рекурсивном вызове, обратите внимание, что мы не делаемдаже нужно увеличивать переменные внутри процедуры, например:
(define (numpos lst)
(cond
((null? lst) 0)
((>= (car lst) 0) (+ 1 (numpos (cdr lst))))
(else (numpos (cdr lst)))))
Ключ к пониманию того, как это работает, находится здесь:
(+ 1 (numpos (cdr lst)))
Мы добавляем единицу к результату рекурсиии мы продолжаем делать это для каждого положительного числа, пока не достигнем конца списка и не добавим ноль в конце.
В своем коде вы написали следующее: (+ num_pos 1)
, но это выражениене изменение значения num_pos
, это просто добавление единицы к нулю, но никогда сохранение результата сложения!
Теперь мы можем определить переменные с помощьюправильные значения, шЧтобы вычислить num_pos
только с помощью процедуры, можно легко определить значение num_neg
:
(define num_pos (numpos lst))
(define num_neg (- (length lst) num_pos))
Существует много способов решения этой проблемы. Ознакомившись с рекурсивными процедурами, вы обнаружите, что существует множество встроенных процедур, которые позволяют быстро найти решение распространенных проблем. На самом деле, идиоматический способ ответить на ваш вопрос - использовать count
:
(define (numpos lst)
(count (lambda (n) (>= n 0))
lst))