Вектори
У Scheme вектор — це ще одна фундаментальна структура даних для групування значень. На відміну від списків, вектори — це індексовані колекції елементів фіксованого розміру, які забезпечують швидший довільний доступ і оновлення. Кожен елемент у векторі може бути будь-якого типу, включно з іншим вектором. Вектори позначаються символом #, за яким йдуть дужки: #(1 2 3).
Хоча вектори та списки можуть виглядати схожими, вони служать різним цілям у програмуванні на Scheme:
Списки частіше використовують для рекурсивних операцій і динамічних структур, оскільки їхня реалізація через зв’язані вузли дозволяє ефективно змінювати початок і обходити їх рекурсивно.
Вектори, навпаки, оптимізовані для ситуацій, де потрібен довільний доступ до елементів або оновлення за конкретними індексами — вони краще підходять для таблиць пошуку, конфігурацій фіксованого розміру або індексованих операцій, критичних до продуктивності.
По суті, списки — природний вибір для рекурсивних алгоритмів і даних з динамічним розміром, тоді як вектори найкраще підходять, коли важливі фіксований розмір або індексований доступ.
Прості вектори
(vector 1 2 3)- Створює вектор із трьох елементів:
1,2та3.
Результат: #(1 2 3)
Доступ до елементів вектора
Доступ до елементів у векторі здійснюється за допомогою процедури vector-ref — вона отримує елемент за вказаним індексом (починаючи з 0).
(define my-vector (vector 1 2 3))
(vector-ref my-vector 0) ; Отримати елемент з індексом 0
(vector-ref my-vector 1) ; Отримати елемент з індексом 1Ітерація: обробка кожного елемента вектора
Вектор можна перебирати циклом або рекурсією. Scheme надає vector-length для визначення розміру вектора. Ось простий цикл для друку кожного елемента вектора:
(define (print-elements vec)
(let loop ((i 0))
(if (< i (vector-length vec))
(begin
(lumi-message (number->string (vector-ref vec i))) ; Вивести елемент
(loop (+ i 1))) ; Перейти до наступного індексу
(lumi-message "done")))) ; Кінець циклу- Базовий випадок: якщо індекс
iдосягає довжини вектора, зупинити цикл. - Рекурсивний випадок: вивести елемент з індексом
i, потім збільшитиi.
Приклад використання
(print-elements (vector 1 2 3))Результат:
"1""2""3"
Результат: "done"
Змішані вектори
Вектори можуть містити елементи різних типів, включно з рядками, логічними значеннями, числами, іншими векторами або навіть результатом виразів:
(vector 42 "hello" #t (vector 1 2) (+ 3 4))Це створює вектор із:
- числа (
42) - рядка (
"hello") - логічного значення (
#t) - іншого вектора (
#(1 2)) - результату виразу (
(+ 3 4), який обчислюється як7)
Результат: #(42 "hello" #t #(1 2) 7)
Побудова векторів
Вектори створюють за допомогою vector або make-vector — для вектора фіксованого розміру з початковим значенням.
(make-vector 5 0)Створює вектор розміром 5 з усіма елементами, ініціалізованими як 0.
Результат: #(0 0 0 0 0)
Оновлення векторів
Процедура vector-set! оновлює елемент у векторі за вказаним індексом.
(define my-vector (vector 1 2 3))
(vector-set! my-vector 1 42) ; Встановити другий елемент як 42
my-vectorРезультат: #(1 42 3)
Перевірка векторів
Процедура vector? перевіряє, чи дане значення є вектором.
(vector? (vector 1 2 3)) ; Перевірити, чи #(1 2 3) є вектором
(vector? 42) ; Перевірити, чи 42 є векторомРезультат:
(vector? (vector 1 2 3))повертає#t(істина)(vector? 42)повертає#f(хибність)
Вектори та передавання за посиланням
У Scheme вектори є змінними та передаються за посиланням. Це означає, що коли ви передаєте вектор функції, функція може безпосередньо змінювати вихідний вектор. Будь-які зміни, внесені до вектора всередині функції, також відображатимуться поза нею. Така поведінка корисна для ефективного обміну й оновлення даних між функціями, але вимагає обережності, щоб уникнути небажаних побічних ефектів.
Приклад: зміна вектора у функції
Ось приклад, який демонструє, як вектори передаються за посиланням і змінюються:
(define (modify-vector vec index new-value)
(vector-set! vec index new-value)) ; Оновити вектор за вказаним індексом
(define my-vector (vector 10 20 30))
(modify-vector my-vector 1 99) ; Змінити другий елемент на 99
my-vector ; Вихідний вектор тепер оновленоРезультат: #(10 99 30)
Покрокове пояснення
- Створення вектора:
my-vectorініціалізується значеннями10,20та30. - Передача до функції:
my-vectorпередається доmodify-vectorразом із індексом і новим значенням для оновлення. - Зміна у функції: процедура
vector-set!оновлює значення за вказаним індексом безпосередньо у вихідному векторі. - Відображення змін: оскільки вектори передаються за посиланням, зміни, внесені у функції, відображаються у вихідному векторі.
Наслідки передавання за посиланням
- Продуктивність: передавання векторів за посиланням ефективне, оскільки уникає копіювання великих структур.
- Побічні ефекти: будьте обережні, передаючи вектори між функціями, щоб уникнути ненавмисних змін спільних даних.
Операції над векторами
Scheme надає кілька вбудованих процедур для роботи з векторами, зокрема:
vector-length: повертає кількість елементів у векторі.vector->list: перетворює вектор на список.list->vector: перетворює список на вектор.
(vector-length (vector 1 2 3)) ; Повертає 3
(vector->list (vector 1 2 3)) ; Перетворити вектор на список: (1 2 3)
(list->vector (list 1 2 3)) ; Перетворити список на вектор: #(1 2 3)Результат:
(vector-length (vector 1 2 3))повертає3(vector->list (vector 1 2 3))повертає(1 2 3)(list->vector (list 1 2 3))повертає#(1 2 3)
Вкладені вектори
Вектори в Scheme можуть містити інші вектори як елементи, створюючи вкладену структуру.
(define nested-vector (vector (vector 1 2) (vector 3 4) (vector 5)))Створює вектор із трьох елементів, кожен з яких сам є вектором.
Результат: #(#(1 2) #(3 4) #(5))
Доступ до вкладених даних
Щоб отримати доступ до елементів у вкладеному векторі, використовуйте vector-ref кілька разів для навігації структурою.
Приклад: доступ до елементів
(vector-ref nested-vector 0) ; Отримати перший елемент: #(1 2)
(vector-ref (vector-ref nested-vector 0) 1) ; Отримати другий елемент першого вектора: 2Резюме
- Вектори у Scheme — це індексовані структури даних фіксованого розміру.
- Використовуйте
vectorдля створення вектора,vector-refдля доступу до елементів іvector-set!для їх оновлення. - Вбудовані процедури, такі як
vector-length,vector->listтаlist->vector, забезпечують гнучкі операції. - Вкладені вектори дозволяють створювати складні ієрархічні структури даних.