⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data-structures.scm

📁 Scheme跨平台编译器
💻 SCM
📖 第 1 页 / 共 2 页
字号:
    (##sys#check-exact start2 'substring-ci=?)    (##core#inline "C_substring_compare_case_insensitive"		   s1 s2 start1 start2 len) ) )(define (substring-ci=? s1 s2 #!optional (start1 0) (start2 0) len)  (##sys#substring-ci=? s1 s2 start1 start2 len) );;; Split string into substrings:(define string-split  (lambda (str . delstr-and-flag)    (##sys#check-string str 'string-split)    (let* ([del (if (null? delstr-and-flag) "\t\n " (car delstr-and-flag))]	   [flag (if (fx= (length delstr-and-flag) 2) (cadr delstr-and-flag) #f)]	   [strlen (##sys#size str)] )      (##sys#check-string del 'string-split)      (let ([dellen (##sys#size del)] 	    [first #f] )	(define (add from to last)	  (let ([node (cons (##sys#substring str from to) '())])	    (if first		(##sys#setslot last 1 node)		(set! first node) ) 	    node) )	(let loop ([i 0] [last #f] [from 0])	  (cond [(fx>= i strlen)		 (when (or (fx> i from) flag) (add from i last))		 (or first '()) ]		[else		 (let ([c (##core#inline "C_subchar" str i)])		   (let scan ([j 0])		     (cond [(fx>= j dellen) (loop (fx+ i 1) last from)]			   [(eq? c (##core#inline "C_subchar" del j))			    (let ([i2 (fx+ i 1)])			      (if (or (fx> i from) flag)				  (loop i2 (add from i last) i2)				  (loop i2 last i2) ) ) ]			   [else (scan (fx+ j 1))] ) ) ) ] ) ) ) ) ) );;; Concatenate list of strings:(define (string-intersperse strs #!optional (ds " "))  (##sys#check-list strs 'string-intersperse)  (##sys#check-string ds 'string-intersperse)  (let ((dslen (##sys#size ds)))    (let loop1 ((ss strs) (n 0))      (cond ((##core#inline "C_eqp" ss '())	     (if (##core#inline "C_eqp" strs '())		 ""		 (let ((str2 (##sys#allocate-vector (fx- n dslen) #t #\space #f)))		   (let loop2 ((ss2 strs) (n2 0))		     (let* ((stri (##sys#slot ss2 0))			    (next (##sys#slot ss2 1)) 			    (strilen (##sys#size stri)) )		       (##core#inline "C_substring_copy" stri str2 0 strilen n2)		       (let ((n3 (fx+ n2 strilen)))			 (if (##core#inline "C_eqp" next '())			     str2			     (begin			       (##core#inline "C_substring_copy" ds str2 0 dslen n3)			       (loop2 next (fx+ n3 dslen)) ) ) ) ) ) ) ) )	    ((and (##core#inline "C_blockp" ss) (##core#inline "C_pairp" ss))	     (let ((stri (##sys#slot ss 0)))	       (##sys#check-string stri 'string-intersperse)	       (loop1 (##sys#slot ss 1)		      (fx+ (##sys#size stri) (fx+ dslen n)) ) ) )	    (else (##sys#not-a-proper-list-error strs)) ) ) ) );;; Translate elements of a string:(define string-translate   (let ([make-string make-string]	[list->string list->string] )    (lambda (str from . to)      (define (instring s)	(let ([len (##sys#size s)])	  (lambda (c)	    (let loop ([i 0])	      (cond [(fx>= i len) #f]		    [(eq? c (##core#inline "C_subchar" s i)) i]		    [else (loop (fx+ i 1))] ) ) ) ) )      (let* ([from	      (cond [(char? from) (lambda (c) (eq? c from))]		    [(pair? from) (instring (list->string from))]		    [else		     (##sys#check-string from 'string-translate)		     (instring from) ] ) ]	     [to	      (and (pair? to)		   (let ([tx (##sys#slot to 0)])		     (cond [(char? tx) tx]			   [(pair? tx) (list->string tx)]			   [else			    (##sys#check-string tx 'string-translate)			    tx] ) ) ) ] 	     [tlen (and (string? to) (##sys#size to))] )	(##sys#check-string str 'string-translate)	(let* ([slen (##sys#size str)]	       [str2 (make-string slen)] )	  (let loop ([i 0] [j 0])	    (if (fx>= i slen)		(if (fx< j i)		    (##sys#substring str2 0 j)		    str2)		(let* ([ci (##core#inline "C_subchar" str i)]		       [found (from ci)] )		  (cond [(not found)			 (##core#inline "C_setsubchar" str2 j ci)			 (loop (fx+ i 1) (fx+ j 1)) ]			[(not to) (loop (fx+ i 1) j)]			[(char? to)			 (##core#inline "C_setsubchar" str2 j to)			 (loop (fx+ i 1) (fx+ j 1)) ]			[(cond-expand [unsafe #f] [else (fx>= found tlen)])			 (##sys#error 'string-translate "invalid translation destination" i to) ]			[else 			 (##core#inline "C_setsubchar" str2 j (##core#inline "C_subchar" to found))			 (loop (fx+ i 1) (fx+ j 1)) ] ) ) ) ) ) ) ) ) )(define (string-translate* str smap)  (##sys#check-string str 'string-translate*)  (##sys#check-list smap 'string-translate*)  (let ([len (##sys#size str)])    (define (collect i from total fs)      (if (fx>= i len)	  (##sys#fragments->string	   total	   (reverse 	    (if (fx> i from) 		(cons (##sys#substring str from i) fs)		fs) ) )	  (let loop ([smap smap])	    (if (null? smap) 		(collect (fx+ i 1) from (fx+ total 1) fs)		(let* ([p (car smap)]		       [sm (car p)]		       [smlen (string-length sm)]		       [st (cdr p)] )		  (if (##core#inline "C_substring_compare" str sm i 0 smlen)		      (let ([i2 (fx+ i smlen)])			(when (fx> i from)			  (set! fs (cons (##sys#substring str from i) fs)) )			(collect 			 i2 i2			 (fx+ total (string-length st))			 (cons st fs) ) ) 		      (loop (cdr smap)) ) ) ) ) ) )    (collect 0 0 0 '()) ) );;; Chop string into substrings:(define (string-chop str len)  (##sys#check-string str 'string-chop)  (##sys#check-exact len 'string-chop)  (let ([total (##sys#size str)])    (let loop ([total total] [pos 0])      (cond [(fx<= total 0) '()]	    [(fx<= total len) (list (##sys#substring str pos (fx+ pos total)))]	    [else (cons (##sys#substring str pos (fx+ pos len)) (loop (fx- total len) (fx+ pos len)))] ) ) ) )	   ;;; Remove suffix(define (string-chomp str #!optional (suffix "\n"))  (##sys#check-string str 'string-chomp)  (##sys#check-string suffix 'string-chomp)  (let* ((len (##sys#size str))	 (slen (##sys#size suffix)) 	 (diff (fx- len slen)) )    (if (and (fx>= len slen)	     (##core#inline "C_substring_compare" str suffix diff 0 slen) )	(##sys#substring str 0 diff)	str) ) );;; Defines: sorted?, merge, merge!, sort, sort!;;; Author : Richard A. O'Keefe (based on Prolog code by D.H.D.Warren);;;;;; This code is in the public domain.;;; Updated: 11 June 1991;;; Modified for scheme library: Aubrey Jaffer 19 Sept. 1991;;; Updated: 19 June 1995;;; (sorted? sequence less?);;; is true when sequence is a list (x0 x1 ... xm) or a vector #(x0 ... xm);;; such that for all 1 <= i <= m,;;;	(not (less? (list-ref list i) (list-ref list (- i 1)))).; Modified by flw for use with CHICKEN:;(define (sorted? seq less?)    (cond	((null? seq)	    #t)	((vector? seq)	    (let ((n (vector-length seq)))		(if (<= n 1)		    #t		    (do ((i 1 (+ i 1)))			((or (= i n)			     (less? (vector-ref seq i)				    (vector-ref seq (- i 1))))			    (= i n)) )) ))	(else	    (let loop ((last (car seq)) (next (cdr seq)))		(or (null? next)		    (and (not (less? (car next) last))			 (loop (car next) (cdr next)) )) )) ));;; (merge a b less?);;; takes two lists a and b such that (sorted? a less?) and (sorted? b less?);;; and returns a new list in which the elements of a and b have been stably;;; interleaved so that (sorted? (merge a b less?) less?).;;; Note:  this does _not_ accept vectors.  See below.(define (merge a b less?)    (cond	((null? a) b)	((null? b) a)	(else (let loop ((x (car a)) (a (cdr a)) (y (car b)) (b (cdr b)))	    ;; The loop handles the merging of non-empty lists.	 It has	    ;; been written this way to save testing and car/cdring.	    (if (less? y x)		(if (null? b)		    (cons y (cons x a))		    (cons y (loop x a (car b) (cdr b)) ))		;; x <= y		(if (null? a)		    (cons x (cons y b))		    (cons x (loop (car a) (cdr a) y b)) )) )) ));;; (merge! a b less?);;; takes two sorted lists a and b and smashes their cdr fields to form a;;; single sorted list including the elements of both.;;; Note:  this does _not_ accept vectors.(define (merge! a b less?)    (define (loop r a b)	(if (less? (car b) (car a))	    (begin		(set-cdr! r b)		(if (null? (cdr b))		    (set-cdr! b a)		    (loop b a (cdr b)) ))	    ;; (car a) <= (car b)	    (begin		(set-cdr! r a)		(if (null? (cdr a))		    (set-cdr! a b)		    (loop a (cdr a) b)) )) )    (cond	((null? a) b)	((null? b) a)	((less? (car b) (car a))	    (if (null? (cdr b))		(set-cdr! b a)		(loop b a (cdr b)))	    b)	(else ; (car a) <= (car b)	    (if (null? (cdr a))		(set-cdr! a b)		(loop a (cdr a) b))	    a)));;; (sort! sequence less?);;; sorts the list or vector sequence destructively.  It uses a version;;; of merge-sort invented, to the best of my knowledge, by David H. D.;;; Warren, and first used in the DEC-10 Prolog system.	 R. A. O'Keefe;;; adapted it to work destructively in Scheme.(define (sort! seq less?)    (define (step n)	(cond	    ((> n 2)		(let* ((j (quotient n 2))		       (a (step j))		       (k (- n j))		       (b (step k)))		    (merge! a b less?)))	    ((= n 2)		(let ((x (car seq))		      (y (cadr seq))		      (p seq))		    (set! seq (cddr seq))		    (if (less? y x) (begin			(set-car! p y)			(set-car! (cdr p) x)))		    (set-cdr! (cdr p) '())		    p))	    ((= n 1)		(let ((p seq))		    (set! seq (cdr seq))		    (set-cdr! p '())		    p))	    (else		'()) ))    (if (vector? seq)	(let ((n (vector-length seq))	      (vec seq))	  (set! seq (vector->list seq))	  (do ((p (step n) (cdr p))	       (i 0 (+ i 1)))	      ((null? p) vec)	    (vector-set! vec i (car p)) ))	;; otherwise, assume it is a list	(step (length seq)) ));;; (sort sequence less?);;; sorts a vector or list non-destructively.  It does this by sorting a;;; copy of the sequence.  My understanding is that the Standard says;;; that the result of append is always "newly allocated" except for;;; sharing structure with "the last argument", so (append x '()) ought;;; to be a standard way of copying a list x.(define (sort seq less?)    (if (vector? seq)	(list->vector (sort! (vector->list seq) less?))	(sort! (append seq '()) less?)));;; Binary search:(define binary-search  (let ([list->vector list->vector])    (lambda (vec proc)      (if (pair? vec)	  (set! vec (list->vector vec))	  (##sys#check-vector vec 'binary-search) )      (let ([len (##sys#size vec)])	(and (fx> len 0)	     (let loop ([ps 0]			[pe len] )	       (let ([p (fx+ ps (##core#inline "C_fixnum_divide" (fx- pe ps) 2))])		 (let* ([x (##sys#slot vec p)]			[r (proc x)] )		   (cond [(fx= r 0) p]			 [(fx< r 0) (and (not (fx= pe p)) (loop ps p))]			 [else (and (not (fx= ps p)) (loop p pe))] ) ) ) ) ) ) ) ) ); Support for queues;; Written by Andrew Wilcox (awilcox@astro.psu.edu) on April 1, 1992.;; This code is in the public domain.; ; (heavily adapated for use with CHICKEN by felix);; Elements in a queue are stored in a list.  The last pair in the list; is stored in the queue type so that datums can be added in constant; time.(define (make-queue) (##sys#make-structure 'queue '() '()))(define (queue? x) (##sys#structure? x 'queue))(define (queue-empty? q)  (##sys#check-structure q 'queue 'queue-empty?)  (eq? '() (##sys#slot q 1)) )(define queue-first  (lambda (q)    (##sys#check-structure q 'queue 'queue-first)    (let ((first-pair (##sys#slot q 1)))      (cond-expand        [(not unsafe)	(when (eq? '() first-pair)	  (##sys#error 'queue-first "queue is empty" q)) ]       [else] )      (##sys#slot first-pair 0) ) ) )(define queue-last  (lambda (q)    (##sys#check-structure q 'queue 'queue-last)    (let ((last-pair (##sys#slot q 2)))      (cond-expand       [(not unsafe)	(when (eq? '() last-pair)	  (##sys#error 'queue-last "queue is empty" q)) ]       [else] )      (##sys#slot last-pair 0) ) ) )(define (queue-add! q datum)  (##sys#check-structure q 'queue 'queue-add!)  (let ((new-pair (cons datum '())))    (cond ((eq? '() (##sys#slot q 1)) (##sys#setslot q 1 new-pair))	  (else (##sys#setslot (##sys#slot q 2) 1 new-pair)) )    (##sys#setslot q 2 new-pair)     (##core#undefined) ) )(define queue-remove!  (lambda (q)    (##sys#check-structure q 'queue 'queue-remove!)    (let ((first-pair (##sys#slot q 1)))      (cond-expand       [(not unsafe)	(when (eq? '() first-pair)	  (##sys#error 'queue-remove! "queue is empty" q) ) ]       [else] )      (let ((first-cdr (##sys#slot first-pair 1)))	(##sys#setslot q 1 first-cdr)	(if (eq? '() first-cdr)	    (##sys#setslot q 2 '()) )	(##sys#slot first-pair 0) ) ) ) )(define (queue->list q)  (##sys#check-structure q 'queue 'queue->list)  (##sys#slot q 1) )(define (list->queue lst0)  (##sys#check-list lst0 'list->queue)  (##sys#make-structure    'queue lst0   (if (eq? lst0 '())       '()       (do ((lst lst0 (##sys#slot lst 1)))	   ((eq? (##sys#slot lst 1) '()) lst)	 (if (or (not (##core#inline "C_blockp" lst))		 (not (##core#inline "C_pairp" lst)) )	     (##sys#not-a-proper-list-error lst0 'list->queue) ) ) ) ) ); (queue-push-back! queue item); Pushes an item into the first position of a queue.(define (queue-push-back! q item)  (##sys#check-structure q 'queue 'queue-push-back!)  (let ((newlist (cons item (##sys#slot q 1))))    (##sys#setslot q 1 newlist)    (if (eq? '() (##sys#slot q 2))	(##sys#setslot q 2 newlist)))); (queue-push-back-list! queue item-list); Pushes the items in item-list back onto the queue,; so that (car item-list) becomes the next removable item.(define-macro (last-pair lst0)  `(do ((lst ,lst0 (##sys#slot lst 1)))       ((eq? (##sys#slot lst 1) '()) lst)))(define (queue-push-back-list! q itemlist)  (##sys#check-structure q 'queue 'queue-push-back-list!)  (##sys#check-list itemlist 'queue-push-back-list!)  (let* ((newlist (append itemlist (##sys#slot q 1)))	 (newtail (if (eq? newlist '())		       '()		       (last-pair newlist))))    (##sys#setslot q 1 newlist)    (##sys#setslot q 2 newtail)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -