для цикла в схеме

я немного запутался, как я могу построить цикл for в схеме. цикл for должен быть реализован во второй части. где он берет список чисел и вставляет каждый элемент в список в части I, чтобы найти длину. Я был в кабеле, чтобы получить первый элемент, но мне нужен цикл for или что-то еще, чтобы получить такой вывод: '(7 10 5 16 106 37) вот мой код:

#lang racket
; Part I
(define (sequence n)
(cond  [(= n 1)
      (list n)]
[(even? n)
( cons n(sequence( / n 2)))]
[(odd? n) 
( cons n(sequence (+(* n 3) 1))) ] ))

(sequence 3)

; Part II
(define (find-length items)
( cond [(null? items)
      (list items)]
  [find-length(length(sequence(car items))) ]   
  ))

  (find-length '(10 13 16 22 95 158))

вот результат:

 '(3 10 5 16 8 4 2 1)
 7

person Muhsag    schedule 14.02.2013    source источник
comment
Выход, кажется, не соответствует входу. Какой результат вы ожидаете от этого ввода? : (найти длину '(10 13 16 22 95 158))   -  person Óscar López    schedule 15.02.2013
comment
вывод должен быть: '(7 10 5 16 106 37), я получил только первый элемент, который равен 7   -  person Muhsag    schedule 15.02.2013


Ответы (2)


Поясню: вам нужна длина последовательности Коллатца для каждого числа в списке items? Очевидно, это домашнее задание, поэтому на этот раз я не могу дать прямой ответ. Вот общая структура решения, заполните пробелы:

(define (find-length items)
  (if (null? items)           ; if the list is null
      <???>                   ; return the empty list
      (cons                   ; otherwise `cons` the
       (length <???>)         ; length of Collatz sequence of first element
       (find-length <???>)))) ; and recur over the rest of the list

Протестируйте процедуру, результат должен быть таким, как показано ниже:

(find-length '(10 13 16 22 95 158))
=> '(7 10 5 16 106 37)

Обратите внимание, что ваш ответ был почти правильным — базовым случаем для этой процедуры является просто пустой список, а вы забыли вызвать рекурсию. В Scheme, по крайней мере, старайтесь не думать о циклах while, for: реализуйте итерацию с точки зрения рекурсии, это идиоматический способ сделать это. После того, как вы разберетесь с этим, вы можете начать использовать одну из встроенных циклических конструкций доступно в Racket.

person Óscar López    schedule 14.02.2013
comment
Спасибо, но не могли бы вы объяснить, как я могу повторить остальную часть списка, я использовал cdr, но он возвращает список в первую часть, так что принимает только число - person Muhsag; 15.02.2013
comment
@ user2070173 Вы на правильном пути: используйте cdr Обратите внимание, что в последней строке вы НЕ вызываете процедуру sequence — вы вызываете find-length, которая получает список в качестве параметра — так что cdr возвращает правильное значение! - person Óscar López; 15.02.2013
comment
Вам действительно следует взглянуть либо на How to Design Programs, либо на The Little Schemer, любая из этих книг научит вас правильно думать о решении проблем в Scheme. - person Óscar López; 15.02.2013

Я не хочу давать точный ответ, но вы можете перебрать весь список и найти эту длину вот так.

(define (length lst)
(if (null? items)
'()
(+ 1  (length(cdr lst)))))

Таким образом, вы получаете доступ ко всем элементам списка рекурсивно. Он находит, что первый элемент добавляет +1, а затем пытается найти длину списка cdr, которая равна length lst-1. И так до тех пор, пока не дойдет до конца списка.

person Prethia    schedule 28.10.2014