Списки

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

Example 1: Simple List

(list 1 2 3)
  • Создает список из трех элементов: 1, 2 и 3.

Результат: (1 2 3)


Доступ к элементам списка

Доступ к элементам списка осуществляется с помощью процедур car и cdr:

  • car извлекает первый элемент списка.
  • cdr извлекает остальную часть списка (все, кроме первого элемента).

Примеры

(define my-list (list 1 2 3))
(car my-list)  ; Retrieves the first element
(cdr my-list)  ; Retrieves the rest of the list

Результат:

  • (car my-list) возвращает 1
  • (cdr my-list) возвращает (2 3)

Простая рекурсия: обход списка

Рекурсивно вызывая car для cdr списка, вы можете обрабатывать каждый элемент один за другим, пока список не будет пройден. Это составляет основу многих алгоритмов обработки списков.

Пример: печать каждого элемента списка

Вот простая рекурсивная функция для печати каждого элемента списка:

(define (print-elements lst)
  (if (null? lst)
    (lumi-message "done")
    (begin
      (lumi-message (number->string (car lst))) ;; Print the first element
      (print-elements (cdr lst)))))             ;; Process the rest of the list
  • Базовый случай: Если список пуст (null? lst), остановите рекурсию.
  • Рекурсивный случай: Распечатайте первый элемент (car lst), затем вызовите функцию для остальной части списка (cdr lst).

Пример использования

(print-elements (list 1 2 3))

Выход:

  • "1"
  • "2"
  • "3"

Результат: «готово»


Как это работает

  1. Функция извлекает первый элемент списка с помощью car и обрабатывает его.
  2. Затем он вызывает себя вместе с остальной частью списка (cdr).
  3. Этот процесс повторяется до тех пор, пока список не станет пустым (null? lst).

Пример 2: смешанные типы

Списки могут включать элементы разных типов, включая строки, логические значения, числа, другие списки или даже результаты выражений:

(list 42 "hello" #t (list 1 2) (+ 3 4))
  • Это создает список с:
    • Номер (42)
    • Строка ("hello")
    • Логическое значение (#t)
    • Еще один список ((1 2))
    • Результат выражения ((+ 3 4), которое имеет значение 7)

Результат: (42 "hello" #t (1 2) 7)


Эти примеры демонстрируют универсальность списков в Scheme, что делает их мощным инструментом для организации данных и управления ими.

Создание списков

Процедура cons используется для создания нового списка путем объединения элемента с существующим списком.

(cons new-element existing-list)

Пример

(cons 0 (list 1 2 3))
  • Добавляет 0 в начало списка (1 2 3).

Результат: (0 1 2 3)


Проверка списков

Процедура list? проверяет, является ли данное значение списком.

(list? value)

Пример: список?

(list? (list 1 2 3))  ; Checks if (list 1 2 3) is a list
(list? 42)            ; Checks if 42 is a list

Результат:

  • (list? (list 1 2 3)) возвращает #t (истина)
  • (list? 42) возвращает #f (ложь)

Операции со списками

Scheme предоставляет несколько встроенных процедур для работы со списками, в том числе:

  • length: возвращает количество элементов в списке.
  • append: объединяет два или более списков в один.
  • reverse: возвращает новый список с элементами в обратном порядке.
(length (list 1 2 3))          ; Returns 3
(append (list 1 2) (list 3 4)) ; Returns (1 2 3 4)
(reverse (list 1 2 3))         ; Returns (3 2 1)

Результат:

  • (length (list 1 2 3)) возвращает 3
  • (append (list 1 2) (list 3 4)) возвращает (1 2 3 4)
  • (reverse (list 1 2 3)) возвращает (3 2 1)#### Использование list-ref

Процедура list-ref извлекает элемент по указанному индексу списка (индекс, начинающийся с нуля).

(list-ref lst index)
  • lst: список, из которого можно получить элемент.
  • index: индекс, отсчитываемый от нуля, указывающий, какой элемент нужно вернуть.
Пример: ссылка на список
(list-ref (list 10 20 30 40) 2)  ; Retrieves the element at index 2

Результат: 30


Вложенные списки

Списки в Scheme могут содержать другие списки в качестве элементов, создавая вложенную структуру.

Пример: создание вложенного списка

(define nested-list (list (list 1 2) (list 3 4) (list 5)))
  • Создает список из трех элементов, каждый из которых сам по себе является списком.

Результат: ((1 2) (3 4) (5))


Доступ к вложенным данным

Для доступа к элементам вложенного списка вы можете использовать комбинации car и cdr для навигации по структуре.

Пример: доступ к элементам

(car nested-list)              ; Retrieves the first element: (1 2)
(car (car nested-list))        ; Retrieves the first element of the first sublist: 1
(cdr (car nested-list))        ; Retrieves the rest of the first sublist: (2)
(car (cdr (car nested-list)))  ; Retrieves the second element of the first sublist: 2

Объяснение

  1. car nested-list:

    • Извлекает первый элемент nested-list, то есть (1 2).
  2. car (car nested-list):

    • Получает первый элемент (1 2), то есть 1.
  3. cdr (car nested-list):

    • Получает остальную часть (1 2), то есть (2).
  4. car (cdr (car nested-list)):

    • Получает первый элемент (2), то есть 2.

Пример: доступ к элементам из других подсписков

(car (cdr nested-list))        ; Retrieves the second sublist: (3 4)
(car (car (cdr nested-list)))  ; Retrieves the first element of the second sublist: 3

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

Резюме

  • Списки в Scheme — это универсальные и важные структуры данных.
  • Используйте list для создания списка, car и cdr для доступа к элементам и cons для создания списков.
  • Встроенные процедуры, такие как length, append, reverse и list-ref, делают операции со списками простыми и эффективными.
  • Списки могут быть вложенными, что позволяет использовать сложные структуры данных для расширенных вариантов использования.