Вам потребуется написать собственную процедуру, чтобы сделать это в простой старой схеме. Оба приведенных ниже решения будут работать в любой из стандартных схем R4RS, R5RS, R6RS или R7RS.
Рекурсивное решение
Рекурсивное решение может занять список xs
и два индекса a
и b
в качестве аргументов. Если a
и b
равны, то должен быть возвращен пустой список '()
. Если a
равен нулю, то первый элемент списка должен быть cons
добавлен к остальной части подсписка. В противном случае должен быть возвращен подсписок остальных xs
, с a
и b
, уменьшенными на единицу.
(define (sublist xs a b)
(cond ((= a b) '())
((zero? a)
(cons (car xs) (sublist (cdr xs) a (- b 1))))
(else
(sublist (cdr xs) (- a 1) (- b 1)))))
> (sublist '(1 2 3 4 5 6) 1 3)
(2 3)
Обратите внимание, что когда a
равен нулю, первый элемент списка xs
сохраняется (добавляется в результирующий подсписок), но в этом случае последний индекс диапазона должен быть уменьшен, поскольку рабочий список был сокращен спереди. Тем не менее, нам все еще нужен подсписок из индекса 0 в новом рабочем списке.
Аналогично, когда a
еще не равен нулю, первый элемент списка отбрасывается, и вызывается sublist
сокращенный рабочий список; в этом случае оба a
и b
должны быть уменьшены.
Обратите внимание, что этот код не проверяет входы; то есть эта процедура предполагает, что предоставлен действительный ввод. Если a
или b
выходит за пределы допустимого диапазона или b
<<code>a, будут проблемы.
Решение с использованием встроенных процедур списка
Другой подход может использовать встроенные процедуры list-tail
и reverse
. Сначала будет полезна вспомогательная процедура:
(define (dropr xs n)
(reverse (list-tail (reverse xs) n)))
Эта процедура удаляет самые правые элементы n
из списка ввода. Обратите внимание, что встроенная процедура list-tail
возвращает свой список ввода с удаленными первыми элементами k
.
Теперь dropr
и list-tail
можно объединить, чтобы сделать sublist-2
:
(define (sublist-2 xs a b)
(list-tail (dropr xs (- (length xs) b)) a))
Здесь list-tail
удаляет первые a
элементы списка ввода, а dropr
удаляет последние l-b
элементы из списка, где l
- длина списка.
Вывод как и прежде:
> (sublist-2 '(1 2 3 4 5 6) 1 3)
(2 3)