Хранение возвращаемых значений в схеме

 (define (odds lst)
    (if (null? lst)
      lst
      (cons (car lst)
            (if (or (null? lst)
                    (not (pair? (cdr lst))))
              '()
              (odds (cddr lst)))))
      )

Эта функция возвращает элементы с нечетными номерами; моя проблема в том, что я хочу взять список, который он возвращает, и перевернуть его (используя встроенную функцию reverse). Я пытался использовать lambda для его хранения, но результаты не меняются, также пытался использовать set-cons!, но безрезультатно. Концепция использования let в рекурсивной функции, кажется, ускользает от меня. Если бы кто-то мог указать мне в правильном направлении, это было бы очень признательно!


person cphoenix    schedule 06.04.2018    source источник
comment
Если (odds '(1 2 3 4)) выводит '(1 3), то его обратным значением будет (reverse (odds '(1 2 3 4))), а выходом будет '(3 1).   -  person assefamaru    schedule 07.04.2018
comment
Но если предположить, что odds должен возвращать нечетные числа в списке, это не работает так, как вы ожидаете. Например, (odds '(1 3 5 7 9)) выводит '(1 5 9), хотя все элементы этого списка нечетные.   -  person assefamaru    schedule 07.04.2018
comment
@assefamaru Это элементы списка с нечетным индексом, начиная с 1.   -  person molbdnilo    schedule 07.04.2018
comment
Вы можете удалить второй (null? lst), он никогда не будет истинным, и, таким образом, избавиться от or, так как останется только его второй аргумент.   -  person bipll    schedule 07.04.2018
comment
Я пытался использовать lambda для его хранения, как? но результаты не меняются, покажите нам! также пытался использовать set-cons! тоже, безрезультатно. покажи код! Не видя вашего кода, мы вынуждены работать в темноте, что не очень продуктивно и не так полезно вам. В ваших интересах правильно задать вопрос, включая весь соответствующий код и тестовые вызовы с ним, а также их фактический и ожидаемый результат. спрашивать иначе не особенно вежливо.   -  person Will Ness    schedule 08.04.2018
comment
этот вопрос что ты имеешь в виду? пожалуйста, ответь.   -  person Will Ness    schedule 09.04.2018


Ответы (3)


Передайте результат функции в reverse в том месте, где вы хотите перевернуть список:

> (odds '(a b c d e))
'(a c e)
> (reverse (odds '(a b c d e)))
'(e c a)
> (let ((o (reverse (odds '(a b c d e))))) (append o o))
'(e c a e c a)
> (define (reverse-odds ls) (reverse (odds ls)))
> (reverse-odds '(5 6 a 9 "hi"))
'("hi" a 5)
person molbdnilo    schedule 07.04.2018
comment
Меня смущает третья строчка и далее. Могу ли я сделать это внутри самой функции? Например, могу ли я поместить этот let в функцию, и когда я вызываю свою нечетную функцию, она выполняет свою работу И переворачивает список? - person cphoenix; 08.04.2018
comment
Они используют функцию, которую вы определили. Если вам нужна функция, которая возвращает элементы с нечетным индексом в обратном порядке, используйте две функции (например, reverse-odds выше). - person molbdnilo; 08.04.2018

Вот фрагмент, в котором хранится как возврат, так и результат с использованием let*

(define (odds lst)    
  (if(null? lst)
    lst
    (cons (car lst)
       (if (or (null? lst)
               (not(pair? (cdr lst))))
       '()
        (odds (cddr lst))))))

(define data (odds `(1 2 3 4 5 6 7 8 9) ) )

(let ((rev_odds ( reverse data  )))
   ;do stuff with results
   (display rev_odds)
     )
person 138    schedule 07.04.2018
comment
Не могли бы вы уточнить, почему у вас были такие цифры? Под нечетным числом я имел в виду индексы. Буду ли я использовать let* для сохранения окончательного списка, созданного cons, а затем использовать reverse? Мне просто нужно, чтобы результат моей функции был обратным. Спасибо. - person cphoenix; 08.04.2018
comment
Я выбрал их, потому что они представляют индексы. Также вы можете просто использовать let, а не let*, см. изменение выше. - person 138; 08.04.2018

Вы можете не волноваться о возвращаемом значении, если просто cons прямо перейдете к рекурсивному результату.

(define (odds lst)
  (if (null? lst)
    null
    (if (odd? (car lst))
        (cons (car lst)
              (odds (cdr lst)))
        (odds (cdr lst)))))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)

Один из способов представить «возвращаемое» значение — добавить параметр к нашей рекурсивной функции. Ниже мы используем acc в нашей вспомогательной вспомогательной функции loop. Использование подобных параметров является одним из распространенных способов перемещения рекурсивного вызова в концевую позицию.

(define (odds lst)
  (define (loop acc lst)
    (if (null? lst)
        (reverse acc)
        (if (odd? (car lst))
            (loop (cons (car lst) acc)
                  (cdr lst))
            (loop acc
                  (cdr lst)))))
  (loop null lst))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)

Другой способ — представить наше возвращаемое значение в виде лямбды, cont ниже. Мы просто вызываем cont со значением, которое хотим вернуть. В этом случае рекурсивный вызов выглядит немного сложнее, поскольку нам нужно создать лямбду, представляющую новое возвращаемое значение. Дополнительным преимуществом здесь является то, что odds строит результат по порядку; reverse больше не нужен

(define (odds lst (cont identity))
  (if (null? lst)
      (cont null)
      (if (odd? (car lst))
          (odds (cdr lst) (lambda (acc)
                            (cont (cons (car lst) acc))))
          (odds (cdr lst) cont))))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)
person Mulan    schedule 08.04.2018
comment
вопрос был задан плохо. они имели в виду элементы с нечетными номерами, например, по индексу. и они хотят обратить его вспять. - person Will Ness; 08.04.2018