CSC151, Class 28: Vectors
Overview:
* Problems with Lists
* A Solution: Vectors
* Mutability
* Lab
Notes:
* Sorry that HW3 took so long. I hope you at least found it fun.
* I'm gone to the Pew Science and Mathematics Consortium's
Conference on Attracting and Retaining Majors. I hope you have
a good weekend.
* Reese will take notes.
* No reading. No new homework until after break.
----------------------------------------
Teaching by Mr. Stone. Recording and interpretation by Ms. Stoltzfus.
Hey Sam,
Here are the notes I took from Professor Stone's lecture on vectors from
Friday.
-Reese
Vectors
* Data structures similar to a list: both are linear and both can hold
a variety of data types inside
* Different from lists because all elements in a vector are equally
accessible (lists must be taken apart)
-- to get items out of a vector, use (vector-ref VEC NAT#) which returns
the element at position NAT#
--position is calculated in advance
--approach is similar to using arrays in other languages
* How do we build vectors?
--if you know all the elements, use (vector EXP1 EXP2 Ã?EXPN)
---the procedure vector lumps them all together (of any length)
--to create an empty vector, use (vector)
---the empty vector is less common than the null list because it's harder
to change the size of a vector
--to build a vector containing only the same element repeated, use
(make-vector NAT# EXP1)
where the length of the vector is NAT# and EXP1 is the expression
at each position in the vector
---usually this procedure is only used if you are planning to replace
the elements
--to replace elements in a vector, use
(vector-set! VEC NUM NEWVAL)
where VEC is the name of the vector, NUM is the position you want
to change and NEWVAL is the new value you want in that position.
--- !(bang) indicates a side effect operation. This means that
the procedure permanently changes something in whatever you are
using it with. Side effect operations return no useful values
(usually done when you don't care what you get back)
---this effect is different from the binding in let, because the contents
at a position actually change.
*Traversing vectors:
--recursion over position number (using natural numbers)
--you can also skip around (random-access structure)
--two kinds: 1) destructive (replacing elements) 2) non-destructive (creating a new vector)
-Examples
Destructive:
(define square-elements! ;;! Indicates the contents of the vector will change
(lambda (vec)
(let ((len (vector-length vec))) ;; we will commonly want to know the length
;; can recurse forwards or backwards since access is just as easy
(let loop ((position 0))
(if (< position len) ;; this is a one-way if (we use it because it's a side-effect procedure
(begin
;;begin performs several side-effect operations in a row)
;;the final operation takes over the whole value of begin
(vector-set! Vec position (square (vector-ref vec pos)))
;; square is a procedure that has been defined elsewhere
(loop (+ position 1))))))))
;; this program returns nothing (or an unspecified void value)
> (define sample (vector 1 2 7 8))
> (square-elements! Sample)
> sample
#(1 4 49 81)
Non-destructive:
(define square-elements
(lambda (vec)
(let ((len (vector-length vec))
(new-vec (make-vector len)))
(let loop ((position 0))
(if (= position len)
new-vec ;; we return a value in this case because otherwise the user wonÃ?t have access
(begin
(vector-set! New-vec position (square (vector-ref vec position)))
(loop (+ position 1))))))))
> (square-elements sample)
> #(1 16 49 6561)