我的任务是制作一个带有两个文件的方案函数,一个“主文件”和一个“wordfile”。然后,该函数计算主文件中的行数,字数和字符数。单词由换行符/制表符/空格分隔。该函数还必须使用wordfile(包含一组单词)并计算在mainfile中找到wordfile中单词的时间。然后它打印出行数,单词和字符......然后是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
用于调试:
(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
中的调试输出。
我忘了添加输入文件,这里是:
AA
1234
5678
9000
1234
1234
aaaa aaaa 9000 aaaa
aaaa
WORD0:
aaaa 1234
所以我将(eq? (car (car wset)) word)
更改为(string=? (car (car wset)) word)
,因为我正在比较字符串,这是我的新错误。
;The object word, passed as an argument to string=?, is not a string.
不过,字应该是一个字符串。在命中错误之前,调试输出也是????.
。
所以我发现了我真正的问题。我正在制作'((word 0))
列表(成对),它只是成对word
。但是当我将其更改为(cons (word 0))
时,我收到aaaa
不适用的错误。有没有办法制作一对字符串和数字的列表?像哈希?对不起,我很擅长计划。
答案 0 :(得分:0)
这条线看起来很可疑:
(append nset (append ((car(car(wset))) (+ (cadr(car(wset))) 1)) (cdr wset))))
首先,append
是非破坏性的。它不会更改nset
的值或内容,只会返回附加内容的新列表。你似乎没有对append
的返回值做任何事情,这意味着它是一个无操作。
其次,((car(car(wset)))
向我建议你正在考虑其他语言的语法,而你可能会改为(car (car wset))
。 (括号在Scheme中很重要。你不能有多于或少于要求。)与你的(cadr(car(wset)))
同上,我认为你的意思是(cadr (car wset))
。