在commonlisp中查找字符频率
例如,如果我输入字符序列 “你好世界”H=1e=1l=3o-2r=1w=1d=1 有人能帮我吗 我在网上找到了这个,但我不明白我想要一个更简单的在commonlisp中查找字符频率,lisp,common-lisp,Lisp,Common Lisp,例如,如果我输入字符序列 “你好世界”H=1e=1l=3o-2r=1w=1d=1 有人能帮我吗 我在网上找到了这个,但我不明白我想要一个更简单的 (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)
(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")
这段代码并不难理解。它打开文件并将其读入字符串。同时,它还制作了一个数组来保存结果(大小为256,因为理论上,我猜非打印字符数可能超过128)。然后它在数组上循环并增加数组中相应的元素。例如,“a”是32,因此当它找到一个“a”时,它会增加数组元素32
最后,它只在可打印的字符结果上循环并打印出来。我倾向于同意drysdam。我已经有一段时间没有接触过任何常见的Lisp代码了,并且能够像他所描述的那样,以一般的理解来阅读这个示例 我不知道您使用的是哪种Lisp环境,但即使在裸CLREPL(read-eval-print-loop)中,您也可以要求系统
(描述“一些未知符号)
。如果你碰巧“被迫”使用Emacs,它有很多功能
我知道这是你今天第二个与lisp相关的问题。也许最好点击一些s.上面的代码非常特定于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
格式指令打印字符,就像通过prin1
我将任务分为两个较小的任务一样:
从文件读取并返回字符串
计算字符串中字符的字母频率
对于,可以使用文件字符串函数()
例如,可以使用“bag”数据结构和fset包库():
是的,我也极力推荐那本书。事实上,我几乎没有做过任何真正的CL编程,我仍然能够理解引用的代码,因为我读过那本书。你读取文件的方法不好,特别是如果你的文件可以有非ascii字符。文件长度以字节为单位返回长度,但字符可以是一个或多个字节。[已编辑的示例代码格式不正确]最好只循环阅读这行代码。我同意,但我只是使用了原始代码中的方法,没有对其进行太多更改。在这里可以找到更好的:@angus:至少字符串永远不会太短,我相信它会有一个错误的上限。将它与fill-=指针(我认为这些指针是由读取顺序自动设置的)结合起来,“所有”您所做的可能都是在浪费RAM。@Vatine:不,填充指针不是由读取顺序自动处理的。在字符串的末尾会有垃圾字符,然后会错误地计算垃圾字符的频率。@angus READ-SEQUENCE返回上次更新的位置,因此可以设置填充指针(或限制循环)。
(defun letter-freq (str)
(let ((bg (fset:convert 'fset:bag str)))
(fset:do-bag-pairs (value mult bg)
(format t "~a: ~a~%" value mult))))