Skip to content

Instantly share code, notes, and snippets.

@kaushalmodi
Last active October 14, 2015 19:59
Show Gist options
  • Save kaushalmodi/ab487f63727381179f61 to your computer and use it in GitHub Desktop.
Save kaushalmodi/ab487f63727381179f61 to your computer and use it in GitHub Desktop.
;; http://emacs.1067599.n5.nabble.com/How-to-count-the-number-of-occurrences-of-a-character-in-a-string-td371732.html
;; https://gist.github.com/joostkremers/0e07a35c85758a2fcb52
(defvar num-repeats 100000)
(defun count-char-in-string-cl-count (char str)
(cl-count char str))
(defun count-char-in-string-mapcar (char str)
(apply '+ (mapcar (lambda (x) (if (= x char) 1 0))
str)))
(defun count-char-in-string-mapc (char str)
(let ((num-matches 0))
(mapc (lambda (ascii)
(when (eq char ascii)
(setq num-matches (1+ num-matches))))
(append str nil))
num-matches))
(defun count-char-in-string-cdr (char str)
(let ((str-list (append str nil))
(num-matches 0))
(while str-list
(if (= (car str-list) char)
(setq num-matches (1+ num-matches)))
(setq str-list (cdr str-list)))
num-matches))
;; (defun count-char-in-string-split-string (char str)
;; (let ((c (concat "[" (regexp-quote (char-to-string char)) "]")))
;; (length (split-string c str t))))
(defun count-char-in-string-aref (char str)
(let ((count 0)
(end (length str))
(i 0)
x)
(while (< i end)
(setq x (aref str i))
(if (eq char x)
(setq count (1+ count)))
(setq i (1+ i)))
count))
(defun count-char-in-string-string-match (char str)
"Count the number of times CHAR character appears in STR string."
;; (message "\n==========\nstr = %0s" str)
(let* ((num-matches 0)
(ptr 0) ; initiate pointer for string match
match-pos)
(while (<= ptr (length str))
;; (message "ptr = %0d" ptr)
(setq match-pos (string-match-p
(regexp-quote (char-to-string char)) str ptr))
(if match-pos
(progn
(setq ptr (1+ match-pos))
;; (message "match-pos = %0d ptr = %0d" match-pos ptr)
(setq num-matches (1+ num-matches)))
(progn
(setq ptr (1+ (length str))))))
;; (message "%0d occurrence%0s of `%c' char found in \"%s\"."
;; num-matches (if (/= 1 num-matches) "s" "") char str)
num-matches))
(defun count-char-in-string-test (fn)
(let ((bm-result (benchmark num-repeats
'(progn
(funcall fn ?a "abcda")
(funcall fn ?z "abcda")
(funcall fn ?f "falalala")
(funcall fn ?l "falalalaabcds")
(funcall fn ?^ "f^la^lala^dabra^^")
(funcall fn ?\\ "\\falalala\\")))))
(list fn bm-result)))
(defun count-char-in-string-run-tests ()
(insert "\n")
(mapc (lambda (fn)
(let ((res (count-char-in-string-test fn)))
(insert (format ";; %-35s %s\n" (car res) (cadr res)))))
'(cl-count
count-char-in-string-aref
count-char-in-string-cl-count
count-char-in-string-mapcar
count-char-in-string-mapc
count-char-in-string-cdr
count-char-in-string-string-match))
(insert "\n"))
(count-char-in-string-run-tests)
;; cl-count Elapsed time: 1.540646s
;; count-char-in-string-aref Elapsed time: 1.794012s
;; count-char-in-string-cl-count Elapsed time: 1.133700s
;; count-char-in-string-mapcar Elapsed time: 2.033713s (1.163422s in 8 GCs)
;; count-char-in-string-mapc Elapsed time: 2.140363s (1.170861s in 8 GCs)
;; count-char-in-string-cdr Elapsed time: 2.543917s (1.168051s in 8 GCs)
;; count-char-in-string-string-match Elapsed time: 4.002969s (2.516860s in 17 GCs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment