fork download
  1. ; string-replace
  2. ; replace all occurrences of pat in str with rep
  3.  
  4. (define (string-find pat str . s)
  5. (let* ((plen (string-length pat))
  6. (slen (string-length str))
  7. (skip (make-vector plen 0)))
  8. (let loop ((i 1) (j 0))
  9. (cond ((= i plen))
  10. ((char=? (string-ref pat i) (string-ref pat j))
  11. (vector-set! skip i (+ j 1))
  12. (loop (+ i 1) (+ j 1)))
  13. ((< 0 j) (loop i (vector-ref skip (- j 1))))
  14. (else (vector-set! skip i 0)
  15. (loop (+ i 1) j))))
  16. (let loop ((p 0) (s (if (null? s) 0 (car s))))
  17. (cond ((= s slen) #f)
  18. ((char=? (string-ref pat p) (string-ref str s))
  19. (if (= p (- plen 1))
  20. (- s plen -1)
  21. (loop (+ p 1) (+ s 1))))
  22. ((< 0 p) (loop (vector-ref skip (- p 1)) s))
  23. (else (loop p (+ s 1)))))))
  24.  
  25. (define (string-replace str pat rep) ; quadratic
  26. (let ((x (string-find pat str)))
  27. (if (not x) str
  28. (string-append (substring str 0 x) rep
  29. (string-replace (substring str (+ x (string-length pat))
  30. (string-length str)) pat rep)))))
  31.  
  32. (time (begin (string-replace (make-string 1000 #\a) "a" "b") 'done))
  33.  
  34. (define (string-replace str pat rep) ; linear
  35. (let ((str-len (string-length str))
  36. (pat-len (string-length pat)))
  37. (let loop ((pos 0) (xs (list)))
  38. (if (<= str-len pos)
  39. (apply string-append (reverse xs))
  40. (let ((x (string-find pat str pos)))
  41. (if x
  42. (loop (+ pos pat-len)
  43. (cons rep (cons (substring str pos x) xs)))
  44. (loop str-len (cons (substring str pos str-len) xs))))))))
  45.  
  46. (time (begin (string-replace (make-string 1000 #\a) "a" "b") 'done))
Success #stdin #stdout #stderr 0.06s 7364KB
stdin
Standard input is empty
stdout

	
stderr
0.03s CPU time, 0.009s GC time (major), 13022 mutations, 6/141 GCs (major/minor)
0.023s CPU time, 0.005s GC time (major), 12017 mutations, 3/133 GCs (major/minor)