日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

string substitution

發(fā)布時(shí)間:2024/1/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 string substitution 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
(defstruct bufvec (start -1) (used -1) (new -1) (end -1))(defun bref (buf n)(svref (buf-vec buf)(mod n (length (buf-vec buf)))));;;擴(kuò)展setf方法,注意下面調(diào)用的方式 (defun (setf bref) (val buf n)(setf (svref (buf-vec buf)(mod n (length (buf-vec buf))))val))(defun new-buf (len)(make-buf :vec (make-array len)))(defun buf-insert (x b)(setf (bref b (incf (buf-end b))) x))(defun buf-pop (b)(prog1 (bref b (incf (buf-start b)))(setf (buf-used b) (buf-start b)(buf-new b) (buf-end b))))(defun buf-next (b)(when (< (buf-used b) (buf-new b))(bref b (incf (buf-used b)))))(defun buf-reset (b)(setf (buf-used b) (buf-start b)(buf-new b) (buf-end b))) ;;;都設(shè)置成-1,為了實(shí)現(xiàn)對(duì)buffer的清空 (defun buf-clear (b)(setf (buf-start b) -1 (buf-used b) -1(buf-new b) -1 (buf-end b) -1)) ;;只有一種情況buf-used為-1,說(shuō)明到文件結(jié)束時(shí),剛讀入到buffer的字符都匹配,未出現(xiàn)pop邏輯,故-1+1=0,也就是從頭開始princ. (defun buf-flush (b str)(do ((i (1+ (buf-used b)) (1+ i)))((> i (buf-end b)))(princ (bref b i) str))) (setf bref) 它重載了setf方法,為了是mod n 然后得到ring buffer。只有在insert的時(shí)候才調(diào)用了這個(gè)setf方法。n是buf-end +1之后的值,length最后的結(jié)果是buffer的長(zhǎng)度,是個(gè)定值。比方說(shuō)只剩下第二個(gè)b的時(shí)候,buf-end = 3. (3+1) mod 4 =?0,所以接下來(lái)的a就加入到了第一個(gè)位置。
buf-insert 關(guān)鍵就是里面的擴(kuò)展的setf 方法。
buf-next只有在輸入的時(shí)候是從buffer里面來(lái)的時(shí)候才用buf-next。它是先比較當(dāng)前位置used是否小于buf-new,如果是就把下面那個(gè)輸出來(lái)。所以說(shuō)第二b仍舊會(huì)讀出來(lái)進(jìn)行匹配測(cè)試,當(dāng)它執(zhí)行完以后,然后再call buf-next的話,發(fā)現(xiàn)used跟new已經(jīng)相等了,所以只能是read里面讀取數(shù)據(jù)了。
buf-pop ? ?它是從棧出來(lái),只有執(zhí)行了princ才會(huì)輸出到out里面。所以說(shuō)你看zerop pos首先是princ,然后才是出棧。

buf-flush ?是為了解決一種情況:假設(shè)pattern為baro,現(xiàn)在文本中最后幾個(gè)字符為bar。因?yàn)檎麄€(gè)循環(huán)是到文件尾結(jié)束,現(xiàn)在bar還在buffer里面就結(jié)束了,所以將會(huì)顯示不出來(lái)。其他情況的話buf-flush要不要沒(méi)影響。

(defun file-subst (old new file1 file2)(with-open-file (in file1 :direction :input)(with-open-file (out file2 :direction :output:if-exists :supersede)(stream-subst old new in out))))(defun stream-subst (old new in out)(let* ((pos 0)(len (length old)) (buf (new-buf len)) ;buffer的長(zhǎng)度跟pattern串長(zhǎng)度一樣,(from-buf nil))(do ((c (read-char in nil :eof) ;初始時(shí)讀取一個(gè)字符(or (setf from-buf (buf-next buf)) ;因?yàn)橛卸搪番F(xiàn)象,要么從buffer中讀取,要不從流中。(read-char in nil :eof))))((eql c :eof)) ;循環(huán)結(jié)束條件是碰到了結(jié)尾(cond ((char= c (char old pos)) ;如果讀入的字符等于old中的一個(gè)字符(incf pos) ;pos+1,因?yàn)榉彩瞧ヅ涑晒Φ脑?#xff0c;pattern中的指標(biāo)就要加+指到下一位;;內(nèi)部cond判斷兩次(cond ((= pos len) ; 3 因?yàn)樯厦鎝os已經(jīng)加1了,所以說(shuō)只需相等就行了。(princ new out) ;把它輸出來(lái)(setf pos 0) ;pos 變?yōu)?(buf-clear buf)) ;buffer 清空((not from-buf) ; 2 (buf-insert c buf))))((zerop pos) ; 1(princ c out)(when from-buf(buf-pop buf)(buf-reset buf)))(t ; 4(unless from-buf(buf-insert c buf))(princ (buf-pop buf) out)(buf-reset buf)(setf pos 0))))(buf-flush buf out)))start : 當(dāng)我們pop一個(gè)元素,他就會(huì)增加,增加buf-stard。
end ? :當(dāng)我們插入一個(gè)元素的時(shí)候他會(huì)增加,先增加buf-end,然后再往這個(gè)buf-end里面添加值。
used ?: 當(dāng)我們pop完一個(gè)元素,然后就會(huì)調(diào)用bufnext,他會(huì)在里面累加。
new ? : 當(dāng)試著匹配buffer里面的字符時(shí),開始調(diào)用used/new,一旦buffer中匹配開始,new就會(huì)綁定到end,因?yàn)閑nd就相當(dāng)于是buffer里面最后一個(gè)元素,然后調(diào)用buf-next,進(jìn)行迭代匹配,直到used=new。也就是說(shuō)一旦檢測(cè)buffer的話,會(huì)把buffer里面所有的都試著匹配一遍,然后才會(huì)開始接受從read中讀取。

1:ring buffer空間只要跟pattern一樣就行。
2:短路現(xiàn)象中,在b-a-r的過(guò)程中因?yàn)殡m然這個(gè)時(shí)候buf-used< buf-new當(dāng)時(shí)取到的值為nil,所以仍舊是從流中讀取
from-buf意思就是從buf里面讀取數(shù)據(jù)成功。
3:什么時(shí)候第一次給used/new賦值的呢?也就是在第一次pop的時(shí)候進(jìn)行reset的時(shí)候才會(huì)給used/new進(jìn)行賦值。就像圖5,因?yàn)榍懊娴臅r(shí)候used/new都是-1,所以也都是按流讀入的。

Case1:zerop pos 首先表示的是一個(gè)新的匹配,并且前面沒(méi)有字符匹配成功的話,就把他輸出來(lái)。如u/s直接輸出來(lái)了。都沒(méi)有到buffer里面還有一種情況就是這個(gè)字符已經(jīng)在buffer里面了,但是前面沒(méi)有字符匹配成功,他就需要從buffer中出來(lái),并且重新設(shè)置pos為0(指向pattern的第一個(gè)位置)
Case2:當(dāng)匹配開始,也就是說(shuō)前面有字符匹配已經(jīng)匹配上了。當(dāng)讀入的字符不是來(lái)自于buffer(from-buf 為假),就將字符輸入到buffer里面。pos 指定到old string上面。當(dāng)字符與在pattern string的pos +1值一樣時(shí),說(shuō)明整個(gè)串匹配成功。
Case3:pos + 1 跟new string的長(zhǎng)度一樣,并且匹配在這個(gè)位置的元素匹配成功,就輸出一個(gè)新的string。重新把pattern匹配的起始位置設(shè)置為0,因?yàn)槟阋呀?jīng)匹配成功了,下一個(gè)再進(jìn)行匹配的話,只能是從頭開始。把buffer里面的東西請(qǐng)空。 ?因?yàn)橄忍幚硗阞uffer里面的東西,才會(huì)繼續(xù)從讀入新的值。比如當(dāng)你匹配a彈出的時(shí)候,他會(huì)再(setf from-buf (buf-next buf))
Case4:匹配到中途在這個(gè)位置不匹配了。pop第一個(gè)字符出棧,然后reset,并且設(shè)置pos從pattern頭開始重新匹配。因?yàn)槟爿斎氲臅r(shí)候就是兩種情況輸入的,一個(gè)是讀進(jìn)去,一個(gè)是from-buf.所以在你處理的時(shí)候也同樣是兩種情況處理。

首先按照匹配是否成功,然后再按照是否來(lái)自于文件輸入或者是buffer部分讀取。


CL-USER> (char "string" 1) #\t CL-USER> (new-buf 6) #S(BUF :VEC #(0 0 0 0 0 0) :START -1 :USED -1 :NEW -1 :END -1) CL-USER> (length (buf-vec (new-buf 6))) 6 CL-USER> (file-subst " th" "z" "d:/emacs/string.txt" "d:/emacs/stringold.txt") NIL

總結(jié)

以上是生活随笔為你收集整理的string substitution的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。