查找 Common Lisp 中的字符频率
例如,如果我输入字符序列
“Hello world”H = 1 e = 1 l = 3 o - 2 r = 1 w = 1 d = 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)))
(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")
For example if i enter sequence of characters
"Hello world" H = 1 e = 1 l = 3 o - 2 r = 1 w = 1 d = 1
can some one help me
I found this code online but i dont understand it i want a simpler one
(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")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
上面的代码是针对 ASCII 字符的。如果您想对任何可能的字符执行相同的操作,可以使用哈希表。
~@C
格式指令打印字符,就像通过prin1
一样。The above code is quite specific to ASCII characters. If you want to do the same for any possible character, you can use a hash-table.
~@C
format directive prints the charaсter as if byprin1
.我会将任务分成 2 个较小的任务:
1 读取一个文件并返回一个字符串
2 统计字符串中字符的字母频率
For 1,您可以使用文件字符串函数(https://github.com/kugelblitz/young/blob/master/external-helpers .lisp)
对于 2,您可以使用“bag”数据结构,和偏移量包库(http://common-lisp.net/project/fset/):
I would separate the task into 2 smaller tasks:
1 Read from a file and return a string
2 Count the letter frequency of the characters in the string
For 1, you can use the file-string function (https://github.com/kugelblitz/young/blob/master/external-helpers.lisp)
For 2, you could use a 'bag' data structure, and the fset package library (http://common-lisp.net/project/fset/):
这段代码并不难理解。它打开文件并将其读入字符串中。同时,它还创建一个数组来保存结果(大小为 256,因为理论上您可以有超过 128 个的非打印字符,我猜)。然后它循环遍历数组并递增数组中相应的元素。例如,“a”是 32,因此当它找到“a”时,它会将数组元素递增 32。
最后,它仅循环遍历可打印字符结果并将其打印出来。
This code isn't that hard to understand. It opens the file reads it into a string. Meanwhile, it also makes an array to hold the results (size 256 because theoretically you could have non-printing chars above 128, I guess). Then it loops over the array and increments the corresponding element in the array. For instance, 'a' is 32, so when it finds an 'a' it increments array element 32.
At the end it loops over just the printable character results and prints them out.
我倾向于同意drysdam的观点。我已经有一段时间没有接触过任何 Common Lisp 代码了,并且能够以一般的理解来阅读这个示例,正如他所描述的那样。
我不知道你使用的是哪种 Lisp 环境,但即使在裸露的 CL REPL (读取 eval 打印循环)中,你也可以要求系统
(describe 'some-unknown-symbol)< /代码>。如果你碰巧“被迫”使用 Emacs,它有 SLIME
我看到这是你今天第二个与 Lisp 相关的问题。也许读一些书籍会更好。
I would tend to agree with drysdam. I haven't touched any Common Lisp code in a while and was able to read this example with general understanding, as he has described it.
I don't know what kind of Lisp environment you are using but even within bare CL REPL (read eval print loop) you can ask system to
(describe 'some-unknown-symbol)
. And if you happen to be "forced" to use Emacs it has SLIMEy gobful of features.I see this is your second lisp related question today. Perhaps it would be better to hit some books.