2016-09-10 8 views
0

Мне нужно написать функцию в Racket с помощью foldr, которая возьмет список чисел и удалит элементы списка, которые больше любых последующих чисел ,Как использовать foldr в Racket для исключения чисел в списке, который больше, чем любые последующие номера

Пример: (исключить-больше (список 1 2 3 4 5)) следует произвести (1 2 3 4)

я могу сделать это без использования foldr или функции любого более высокого порядка, но я не могу понять это с foldr. Вот что у меня есть:

(define (eliminate-larger lst) 
    (filter (lambda (z) (not(equal? z null))) 
     (foldr (lambda (x y) 
      (cons (determine-larger x (rest lst)) y)) null lst))      
) 

(define (determine-larger value lst) 
    (if (equal? (filter (lambda (x) (>= x value)) lst) lst) 
     value 
     null) 
) 

определить, больше будет принимать значения и список, и вернуть это значение, если оно больше или равно все элементы в списке. Если нет, он возвращает null. Теперь функция «исключающая больший» пытается пройти через список и передать каждое значение для определения большего, а также список каждого числа после него. Если это «хорошее» значение, оно будет возвращено и помещено в список, если в список не входит нуль. Затем в конце нули отфильтровываются. Моя проблема заключается в получении списка чисел, которые следуют за текущим числом в функции foldr. Использование «rest lst» не работает, так как оно не выполняется рекурсивно. Как получить оставшиеся числа после x в foldr?

ответ

1

Я действительно надеюсь, что я не делаю свою домашнюю работу для вас, но здесь иду ...

Как получить остаток чисел после й в foldr?

Поскольку вы потребляя список справа, вы можете структурировать аккумулятор таким образом, что «остальные цифр после й» доступны в качестве аргумента memo.

(define (eliminate-larger lst) 
    (foldr 
    (lambda (member memo) 
     (if (andmap (lambda (n) (<= member n)) memo) 
     (cons member memo) 
     memo)) 
    '() 
    lst)) 
(eliminate-larger (list 1 2 3 5 4)) ;; (1 2 3 4) 

Это правда наивный решение, как вы вынуждены пройти весь аккумулятор с каждой итерации, но вы можете легко поддерживать максимальное значение, в дополнение к записке, и сравнить против этого каждый раз, когда через ,

+0

Это работает, спасибо! Я пытаюсь прочитать о том, как работает andmap, но я не совсем понимаю, что он делает. –

+0

'andmap' используется для проверки того, что' member' является '<=' каждым элементом в списке аккумуляторов. По сравнению с использованием функции, подобной 'filter', у нее есть дополнительное преимущество для возврата раньше, если _any_ приложение предоставленного proc возвращает' # f' (например, '(<= 5 4)'). – pdoherty926

+0

@KeithCalderwood Если вы удовлетворены этим ответом, не могли бы вы принять его? – pdoherty926

0

следующие работы:

(define (el lst) 
    (define (inner x lsti) 
    (if(empty? lsti) (list x) 
     (if(<= x (apply max lsti)) 
      (cons x lsti) 
      lsti))) 
    (foldr inner '() lst)) 

(el (list 1 2 3 5 4)) 

Выход:

'(1 2 3 4) 

версия конд может быть предпочтительнее:

(define (el lst) 
    (define (inner x lsti) 
    (cond 
     [(empty? lsti) (list x)] 
     [(<= x (apply max lsti)) (cons x lsti)] 
     [else lsti] )) 
    (foldr inner '() lst))