0

我的任务是制作一个接收两个文件的方案函数,一个“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不适用的错误。有没有办法制作成对的字符串和数字列表?像哈希?对不起,我对计划很陌生。

4

1 回答 1

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

于 2013-04-17T01:08:20.640 回答