例如,如果我输入字符序列
“Hello world”H = 1 e = 1 l = 3 o - 2 r = 1 w = 1 d = 1
可以帮助我一些人
我在网上找到了这个code,但我不明白它我想要一个更简单的
(defun letter-freq (file)
(with-open-file (stream file)
(let ((str (make-string (file-length stream)))
(arr (make-array 256 :element-type 'integer :initial-element 0)))
(read-sequence str stream)
(loop for c across str do (incf (aref arr (char-code c))))
(loop for c from 32 to 126 for i from 1 do
(format t "~c: ~d~a"
(code-char c) (aref arr c)
(if (zerop (rem i 8)) #\newline #\tab))))))
(letter-freq "test.lisp")
答案 0 :(得分:4)
以上代码非常特定于ASCII字符。如果要对任何可能的字符执行相同操作,可以使用哈希表。
(defun letter-freq (file)
(with-open-file (stream file)
(let ((str (make-string (file-length stream)))
(ht (make-hash-table)))
(read-sequence str stream)
(loop :for char :across str :do
(incf (gethash char ht 0)))
(maphash (lambda (k v)
(format t "~@C: ~D~%" k v))
ht))))
~@C
format指令打印charaсter,就像prin1
一样。
答案 1 :(得分:2)
我会将任务分成两个较小的任务:
中字符的字母频率对于1,您可以使用文件字符串函数(https://github.com/kugelblitz/young/blob/master/external-helpers.lisp)
对于2,您可以使用'bag'数据结构和fset包库(http://common-lisp.net/project/fset/):
(defun letter-freq (str)
(let ((bg (fset:convert 'fset:bag str)))
(fset:do-bag-pairs (value mult bg)
(format t "~a: ~a~%" value mult))))
答案 2 :(得分:1)
这段代码并不难理解。它打开文件将其读入字符串。同时,它还会生成一个数组来保存结果(大小为256,因为理论上你可以将非打印字符放在128以上,我猜)。然后它遍历数组并递增数组中的相应元素。例如,'a'是32,所以当它找到'a'时,它会增加数组元素32。
最后,它只会覆盖可打印的字符结果并打印出来。
答案 3 :(得分:1)