向量类型
; 向量(也可以叫一維數(shù)組) 哈希表 ; 向量 整數(shù)索引 定長(zhǎng)向量(連續(xù)內(nèi)存區(qū)域)和變長(zhǎng)向量; 函數(shù)VECTOR接受任意參數(shù),生成定長(zhǎng)向量(vector) #()(vector 1) #(1)(vector 1 2) #(1 2); 使用vector或者make-array來(lái)創(chuàng)建打算修改的向量; make-array應(yīng)用很廣泛,多維變長(zhǎng)都行; 一個(gè)必要參數(shù)是數(shù)組長(zhǎng)度,被訪問(wèn)前設(shè)置其值(make-array 5 :initial-element nil) ;#(nil nil nil nil nil); 創(chuàng)建變長(zhǎng)向量,得需要填充指針(make-array 5 :fill-pointer 0) ;#(); (vector-push ) ;填充指針+1,返回位置; (vector-pop) ;填充指針-1,返回元素; 當(dāng)前也不是變長(zhǎng)的,最多5個(gè)元素,如果需要變長(zhǎng)則:adjustable t(defparameter *x* (make-array 5 :fill-pointer 0))(vector-push 'b *x*)(vector-push 'a *x*)(vector-pop *x*); 向量的子類型,特化向量只保存某一類型的,訪問(wèn)快存儲(chǔ)緊湊; 字符串就是一種特化向量; 初始值為空的變長(zhǎng)字符串(defparameter *y* (make-array 5 :fill-pointer 0?:adjustable t:element-type 'character)); 位向量 都是01按位操作 #*01010110111 :element-type BIT; 作為序列的向量之函數(shù)(defparameter *x* (vector 1 2 3))(length *x*) ;3(elt *x* 0)(elt *x* 1)(elt *x* 2); (elt *x* 3) error; elt也是支持setf的位置(setf (elt *x* 2) 33); ;;;;序列迭代函數(shù),對(duì)所有序列管用; (count 項(xiàng) 序列) 出現(xiàn)次數(shù); (find 項(xiàng) 序列) 項(xiàng)或者nil; (position 項(xiàng) 序列)索引或者nil; (remove 項(xiàng) 序列) 移出后的序列,類型和原序列相同; (substitute 新項(xiàng) 項(xiàng) 序列)替換后的序列,類型和原數(shù)列相同(count 3 #(3 4 5 3 6 9)) ;2(find 3 #(3 4 5)) ;3(position #\a "lambda");1(remove #\a "lambda") ;lmbd(substitute 33 3 #(3 4 5)) ;(33 4 5); 改變以上函數(shù)的行為:test :key; 比較參數(shù)(接收一個(gè)函數(shù),默認(rèn)值是EQL):test 接收兩個(gè)參數(shù),返回布爾值的函數(shù); :key是一個(gè)接收單參數(shù)的函數(shù),用于在序列的每個(gè)元素上抽取關(guān)鍵值替代元素自身進(jìn)行匹配(count "foo" ("foo" "bar" "test") :test #'string=)(find 'c #((a 10) (b 20) (c 30)) :key #'first)(find 20 #((a 10) (b 20) (c 30)) :key #'second); 將函數(shù)的效果限定在特定子序列上可以用 :from :end (索引位置)左閉右開(kāi)區(qū)間>=from < end; 倒序參數(shù):from-end 非nil時(shí)起作用; 限制要移出或者替換的個(gè)數(shù):count,默認(rèn)值nil全部; 高階函數(shù)變體,以上五個(gè)函數(shù)加上-IF -IF-NOT; -IF計(jì)數(shù)查找移出替換序列中函數(shù)參數(shù)返回為真的元素; -IF-NOT計(jì)數(shù)查找移出替換序列中函數(shù)參數(shù)不返回真的元素(count-if #'evenp #(1 2 3 4 5)) ;2(count-if-not #'evenp #(1 2 3 4 5)) ;3(position-if #'digit-char-p "abcd0001") ;4(remove-if-not #'(lambda (x) (char= (elt x 0) #\f)) #("f0" "fun" "bar" "boot"))#'alpha-char-p(remove-if-not #'alpha-char-p "a234bc")(remove-duplicates #(1 2 3 4 5 3 4)) ;#(1 2 3 4 5); 整個(gè)序列上的操作; copy-seq返回一個(gè)相同的序列; reverse返回一個(gè)逆序的序列; 這兩個(gè)函數(shù)都不會(huì)復(fù)制元素本身,只有返回的序列是一個(gè)新對(duì)象??????; concatenate 將任意序列返回指定的類型 VECTOR LIST STRING(CONCATENATE 'vector #(1 2 3) '(4 5 6)) ;#(1 2 3 4 5 6)(CONCATENATE 'list #(1 2 3) '(4 5 6)) ;(1 2 3 4 5 6)(CONCATENATE 'string "abc" '(#\4 #\5 #\6)) ;"abc456"; 排序與合并; sort; stable-sort 不會(huì)重排被謂詞視為等價(jià)的元素; 接受一個(gè)序列和一個(gè)兩實(shí)參的謂詞 返回總重排序的序列(sort #("foo" "bar" "baz") #'string<); 這兩個(gè)函數(shù)是破壞性函數(shù),會(huì)或多或少修改它的參數(shù); 1總是對(duì)其返回值做一些事情,賦給一個(gè)變量或者傳給一個(gè)函數(shù); (setf my-sequence (sort my-sequence #'<)); 2除非不在需要傳遞給破壞性函數(shù)的對(duì)象,否則傳給它一個(gè)副本; 可以接收:key用于抽取元素進(jìn)行比較; merge合并(merge 'list '(1 2) '(3 4 1) #'<) ;(1 2 3 4 1); 如果傳遞給merge的序列有序,則結(jié)果有序; 子序列操作; (subseq 序列 開(kāi)始索引 終止索引); 支持setf(defparameter *x* (copy-seq "abcdefg"))(setf (subseq *x* 3 5) "qqqqq");abcqqfg; 兩者之中較短的一個(gè)決定多少被替換; fill函數(shù),填充(fill *x* #\a :start 1 :end 3)省略關(guān)鍵字則全部填充; search函數(shù) 可以查找子序列,方法同position函數(shù)(position #\b "foobarbaz");3(search "bar" "foobar");3; 相同前綴的序列首次分叉的位置mismatch,匹配則返回nil(mismatch "foobar" "foom");3; 可以使用:key :test :from-end :start1 :end1 :start2 :end2關(guān)鍵字; :from-end t 搜索相同后綴在第一個(gè)序列中索引位置; 序列謂詞?; every['evri]每一個(gè)都滿足?; some某個(gè)或某些滿足; notany不是某個(gè)或某些滿足(都不滿足); notevery不是所有的都滿足(有不滿足的); 在序列上迭代測(cè)試一個(gè)布爾謂詞(every #'evenp #(1 2 3 4 5)) nil; every 謂詞失敗時(shí)返回假,否則真; some返回謂詞返回的第一個(gè)非nil值,否則nil; notany在謂詞滿足時(shí)返回假,從未滿足返回真; notevery在謂詞失敗時(shí)返回真,謂詞總是滿足返回假(every #'evenp #(1 2 3 4 5)) ;nil(some #'evenp #(1 2 3 4 5)) ;t(notany #'evenp #(1 2 3 4 5)) ;nil(notevery #'evenp #(1 2 3 4 5)) ;t(every #'> #(5 4) #(1 2));t; 序列映射函數(shù); map接受一個(gè)n參數(shù)函數(shù)和n個(gè)序列,返回一個(gè)新序列; 和merge concatenate 一樣需要指定返回類型(map 'vector #'* #(1 2 3) #(4 5 6));#(4 10 18); map-into不產(chǎn)生新序列,而是放到其中一個(gè)里; (map-into a #'+ a b c); map-into 以最短的序列為標(biāo)準(zhǔn)進(jìn)行操作,不會(huì)自動(dòng)擴(kuò)展可調(diào)整向量的大小; reduce; 將序列提煉成一個(gè)單獨(dú)的值,作用在單獨(dú)的序列上; 序列中的前2個(gè)元素放到2參數(shù)函數(shù)中計(jì)算,結(jié)果再和第三個(gè)元素計(jì)算……(reduce #'+ #(1 2 3 4 5 6 7 8 9 10)) ;55; (reduce #'max numbers); 關(guān)鍵字參數(shù):key :from-end :start :end; :initial-value放到第一個(gè)元素之前,如果:from-end t則放到最后一個(gè)元素之后; 哈希表; 可以用任意對(duì)象作為key(MAKE-HASH-TABLE :test EQL); 鍵值默認(rèn)比較是EQL,可以根據(jù)需要改成EQUAL EQUALP EQ(defparameter *h* (make-hash-table))(gethash 'foo *h*) ;nil(setf (gethash 'foo *h*) 'quux)(gethash 'foo *h*) ;quux; gethash其實(shí)返回2個(gè)值,; 一個(gè)是給定鍵下面的值(可能存儲(chǔ)一個(gè)nil),; 另一個(gè)是一個(gè)是否存在該鍵的布爾值; 可以使用MULTIple-VALUE-BIND宏來(lái)處理多重返回值,類似于let的變量綁定(defun show-value (key hash-table)(multiple-value-bind (value present) (gethash key hash-table)(if present(format nil "~a actually present" value)(format nil "~a key not found" value))))(show-value 'foo *h*); 移除鍵值對(duì)(remhash 'foo *h*); 清空哈希表(clrhash *h*); 哈希表迭代; maphash 接受一個(gè)兩參數(shù)函數(shù) 和 哈希表 依次迭代哈希表的鍵值對(duì)(map-hash #'(lambda (k v) (format t "key:~a value:~a~%" k v)) *h*); 迭代過(guò)程中添加或者移除鍵值對(duì)可能會(huì)產(chǎn)生后果; 但可以用setf和gethash更改值,REMHASH移除當(dāng)前項(xiàng)(maphash #'(lambda (k v) (when (< v 10) (remhash k *h*))) *h*); loop宏(loop fro k being the hash-keys in *h* using (hash-value v)do (format t "key:~a value:~a~%" k v))
通過(guò) Wiz 發(fā)布
通過(guò) Wiz 發(fā)布
轉(zhuǎn)載于:https://www.cnblogs.com/aczhanghua/archive/2012/04/11/2441717.html
總結(jié)
- 上一篇: 巴巴运动网学习笔记(36-40)
- 下一篇: 数学符号