有一些更简单的方法可以解决这个问题,但它们涉及到一些额外的语言知识。例如,使用正则表达式在空格处拆分字符串map
并filter
处理每个单词:
(define line "xbox 360")
(define (process line)
(map (lambda (word)
(cond ((string->number word) "number")
(else "word")))
(filter (lambda (str)
(not (equal? str "")))
(regexp-split #px"\\s+" line))))
请注意,接收到的输入是一个字符串,其中包含输入文件中的一行(由过程返回file->lines
)。一般的想法是:逐行读取文件,并使用上面的代码片段依次处理每个文件。
如果您可以在代码中使用更高级的功能,那么上面的方法就可以了。
编辑 :
我编写了一个仅使用列表迭代和read-char
(not peek-char
,它只读取第一个字符并且不会前进到下一个字符) 的版本,但是您会发现这比上述过程要复杂得多:
(define (process line)
(let ((port (open-input-string line)))
(let loop ((char (read-char port))
(acc '()))
(cond ((eof-object? char)
(cond ((null? acc) '())
((string->number (list->string acc)) (list "number"))
(else (list "word"))))
((char-whitespace? char)
(cond ((null? acc)
(loop (read-char port) '()))
((string->number (list->string acc))
(cons "number" (loop (read-char port) '())))
(else
(cons "word" (loop (read-char port) '())))))
(else
(loop (read-char port) (cons char acc)))))))
对于以下测试,两种解决方案都按预期工作:
(process "xbox 360")
> '("word" "number")
(process "1")
> '("number")
(process "a")
> '("word")
(process " ")
> '()
(process "")
> '()
(process " a b 1 a ")
> '("word" "word" "number" "word")