查找 Common Lisp 中的字符频率

发布于 2024-12-13 16:40:12 字数 712 浏览 0 评论 0原文

例如,如果我输入字符序列

“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

草莓酥 2024-12-20 16:40:12

上面的代码是针对 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 一样。

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.

(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 directive prints the charaсter as if by prin1.

空城旧梦 2024-12-20 16:40:12

我会将任务分成 2 个较小的任务:

1 读取一个文件并返回一个字符串
2 统计字符串中字符的字母频率

For 1,您可以使用文件字符串函数(https://github.com/kugelblitz/young/blob/master/external-helpers .lisp

对于 2,您可以使用“bag”数据结构,和偏移量包库(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))))

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/):

(defun letter-freq (str)
  (let ((bg (fset:convert 'fset:bag str)))
    (fset:do-bag-pairs (value mult bg)
                       (format t "~a: ~a~%" value mult))))
左岸枫 2024-12-20 16:40:12

这段代码并不难理解。它打开文件并将其读入字符串中。同时,它还创建一个数组来保存结果(大小为 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.

青春有你 2024-12-20 16:40:12

我倾向于同意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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文