удаление последнего элемента списка (схемы) - PullRequest
12 голосов
/ 15 февраля 2011

Итак, мне нужно удалить последний элемент списка в схеме.

Например, допустим, у меня есть список (1 2 3 4). Мне нужно вернуть:

(1 2 3)

Моя идея:

reverse(list)
car(list)
reverse(list)

Есть ли функция reverse в схеме (ракетка)?

Ответы [ 6 ]

21 голосов
/ 15 февраля 2011

Вы писали: «задний ход, машина, задний ход».Я полагаю, вы хотели написать «реверс, cdr, реверс».В этом решении нет ничего плохого;он линейный по размеру списка, как и любое решение, использующее стандартные списки.

Как код:

;; all-but-last: return the list, not including the last element
;; list? -> list?
(define (all-but-last l) (reverse (cdr (reverse l))))

Если вас беспокоит многократный обход списка или создание ненужной копии другого списка, вы, безусловно, можете избежать этого, написав эту вещь напрямую.*

Учитывая ваше почти решение, я собираюсь предположить, что это не домашняя работа.

Вот как это будет выглядеть в ракетке:

#lang racket

(require rackunit)

;; all-but-last : return the list, except for the last element
;; non-empty-list? -> list?
(define (all-but-last l)
  (cond [(empty? l) (error 'all-but-last "empty list")]
        [(empty? (rest l)) empty]
        [else (cons (first l) (all-but-last (rest l)))]))

(check-equal? (all-but-last '(3 4 5))
              '(3 4))
6 голосов
/ 15 февраля 2011

Существует reverse, но использовать его было бы не очень эффективно. Я предлагаю следующую рекурсивную функцию.

(define (remove-last lst)
    (if (null? (cdr lst))
        '()
        (cons (car lst) (remove-last (cdr lst)))))

(remove-last '(1 2 3 4)) ; returns '(1 2 3)

if проверяет, находится ли он в последнем элементе списка.

5 голосов
/ 15 февраля 2011

SRFI 1 (активировать в Racket с помощью (require srfi/1)) имеет функцию drop-right:

 (drop-right '(1 2 3 4) 1)   ; => (1 2 3)
2 голосов
/ 15 февраля 2011

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

Хотя я не делал схемы в течение многих лет, так что это насколько я могу пойти.

Кто-то может понять, как это реализовать (если это не домашнее задание, то, вероятно, не следует!)

1 голос
/ 17 января 2015

Я сделал что-то попроще, чем: реверс (список), машина (список), реверс (список), чтобы получить последний элемент, проверить:

(define (last-one liste)
  (if(null? (cdr liste))
     null
     (cons (car liste) (last-one (cdr liste)))
  )
)
0 голосов
/ 29 октября 2011

Я бы написал простую рекурсию, заменив типичный базовый вариант "empty? Mylist" на "empty? (Rest mylist)", чтобы я мог вернуть пустой, когда входной список содержит только 1 элемент.

(define (removelast mylist)
  (cond
    [(empty? (rest mylist)) empty]
    [(cons? mylist) (cons (first mylist) (removelast (rest mylist)))]))

(removelast (list 1 2 3 4 5))

Кстати, этот код находится в Схеме Racket / PLT, подмножестве Схемы.

...