我的任务是制作一个接收两个文件的方案函数,一个“mainfile”和一个“wordfile”。然后该函数计算主文件中的行数、单词数和字符数。单词由换行符/制表符/空格分隔。该函数还必须使用 wordfile(包含一组单词)并计算 wordfile 中的单词在 mainfile 中出现的次数。然后它打印出行数、单词数和字符数……然后是 wordfile 遇到的从大到小排序。这是它应该做什么的示例输入/输出:
1 ]=> (load "ws")
;Loading "ws.scm"... done
;Value: filestatistics
1 ]=> (filestatistics "aa" "word0")
8 10 51
Word usage:
aaaa 4
1234 3
;Value: ()
这是我当前的代码。它没有排序(还),并包含一些额外display
的用于调试的 s:
(define wc
(lambda (srcf l w c)
(if (eof-object? (peek-char srcf))
(begin ;; end of file
(close-port srcf)
(display l)(display " ")
(display w)(display " ")(display c))
(case (read-char srcf) ;; find a word?
((#\space #\tab) (wc srcf l w (+ c 1)))
((#\newline) (wc srcf (+ l 1) w (+ c 1))) ;; new line, increment
(else ;; found a word
(let loop ((i 2)) ;; eat word, 2 for both read-chars
(if (eof-object? (peek-char srcf))
(wc srcf l (+ w 1) (+ c 1))
(case (read-char srcf) ;; end of word?
((#\space #\tab) (wc srcf l (+ w 1) (+ c i)))
((#\newline) (wc srcf (+ l 1) (+ w 1) (+ c i)))
(else (loop (+ i 1)))))))))))
(define countw
(lambda (mfile cfile)
(procw mfile '() (mklist cfile '() '()))))
(define procw
(lambda (file word wset)
(if (eof-object? (peek-char file))
(if (null? word)
(for-each (lambda (w n)
(display w)(display " ")(display n)(newline)))
(procw file '() (addword word wset '())))
(case (peek-char file)
((#\space #\tab #\newline)
(read-char file)
(display ".")
(if (null? word)
(procw file word wset)
(procw file '() (addword word wset '()))))
(else
(display "?")
(if (null? word)
(procw file (string (read-char file)) wset)
(procw file (string-append word (string (read-char file))) wset)))))))
(define addword ;; returns new list
(lambda (word wset nset)
(if (null? wset)
nset
(if (eq? (car (car wset)) word) ;; comparing to front of list in list
(begin
(display "|")
(append nset (append ((car(car(wset))) (+ (cadr(car(wset))) 1)) (cdr wset))))
(addword word (cdr wset) (append nset (car wset)))))))
(define mklist ;; make word list
(lambda (file word wset)
(if (eof-object? (peek-char file))
(begin
(close-port file)
(if (null? word)
wset
(append wset '((word 0)))))
(case (peek-char file)
((#\space #\tab #\newline)
(read-char file)
(if (eq? word '())
(mklist file word wset)
(mklist file '() (append wset '((word 0))))))
(else
(if (eq? word '())
(mklist file (string (read-char file)) wset)
(mklist file (string-append word (string (read-char file))) wset)))))))
(define filestatistics
(lambda (src1 src2)
(begin
(wc (open-input-file src1) 0 0 0)(newline)(newline)
(countw (open-input-file src1) (open-input-file src2)))))
这是我得到的输出:
1 ]=> (load "ws")
;Loading "ws.scm"... done
;Value: filestatistics
1 ]=> (filestatistics "aa" "word0")
8 10 51
????.????.
;The object word, passed as the first argument to car, is not the correct type.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify an argument to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
我不明白为什么我会收到这个错误。因为word
甚至应该是car
. 奇怪的是,代码在出现错误之前一直运行到第二个单词,并且正在运行的第一个单词没有显示“|” (在addword
.
我忘了添加输入文件,它们是:
啊:
1234
5678
9000
1234
1234
aaaa aaaa 9000 aaaa
aaaa
字0:
aaaa 1234
更新 1
所以我改成(eq? (car (car wset)) word)
因为(string=? (car (car wset)) word)
我在比较字符串,这是我的新错误。
;The object word, passed as an argument to string=?, is not a string.
不过,单词应该是一个字符串。调试输出也是????.
在发生错误之前。
更新 2
所以我发现了我真正的问题。我正在制作(成对的)列表,'((word 0))
它只是在字面上制作成对word
。但是当我将其更改为时,(cons (word 0))
我得到一个aaaa
不适用的错误。有没有办法制作成对的字符串和数字列表?像哈希?对不起,我对计划很陌生。