球拍编程:如何使一堆字符变成一个列表?

时间:2018-07-17 06:34:34

标签: functional-programming racket

我当前要执行的操作是在文本文件中将两组整数用作执行计算两组对称差的函数的参数。文本文件的格式是在第一行上有一组数字,每个数字之间都用空格隔开,而在第二行上,还有另一组不同的数字,中间用空格隔开。例如:

1 2 3 4
5 6 1 2

我已经成功实现了一个能够读取文件的函数和一个能够计算两个集合的对称差的函数,该函数将两个被解释为集合的列表作为输入:

function that reads the file:
(define in
  (lambda ()
    (let ((pin(open-input-file (symbol->string (read)))))
      (let g ((x(testchar pin)))
        (if (eof-object? x)
            (begin
              (close-input-port pin)
              '())
            (write x))
            ))))

function that calculates the symmetric difference:
(define Sym-Dif
  (lambda (L1 L2)
    (cond ((null? L1) L2)
          ((union (intersection L1 L2) (intersection L2 L1))))))

为了使用文件中的值,我尝试实现一个辅助函数,该函数检查文本文件中的每个字符,以便当它遇到换行符时,它以递归方式构建第一个列表,当它到达末尾时文件字符,它以递归方式构建第二个列表:

helper function:
(define testchar
  (lambda(x)
    (let f()
      (let ((c(read-char x)))
        (cond
          ((eof-object? c) '())
          ((equal? c #\newline) (begin (list c) (testchar x)))
          ((char? c) (begin (append c)(write c)(testchar x))))))))

但是当运行带有读取文件功能的辅助功能时,我得到#\1#\space#\2#\space#\3#\space#\4#\5#\space#\6#\space#\1#space#\2() 如何使helper函数返回列表而不是字符?

任何帮助将不胜感激。 附言:我正在为此使用Racket博士。

1 个答案:

答案 0 :(得分:1)

“ test.txt”包含两行:

1 2 3 4
5 6 1 2

设置

如何使用内置模块racket/set

(require racket/set)

(define (lines->sets filepath)
  (let* ((lines (file->lines filepath))
         (lists (map (lambda (s) (string-split s " ")) lines)))
    (values (list->set (list-ref lists 0)) (list->set (list-ref lists 1)))))

(define-values (set1 set2) (lines->sets "test.txt"))

(set-symmetric-difference set1 set2)

您的代码的问题是,它计算交点(两个交点的并集),而不是真正的对称差(差的并集)。

输出:

(set "6" "3" "5" "4")

但是如果您希望将其作为列表而不是设置:

作为列表

(define (lines->lists filepath)
  (let* ((lines (file->lines filepath))
        (lists (map (lambda (s) (string-split s " ")) lines)))
    (values (list-ref lists 0) (list-ref lists 1))))

(define-values (list1 list2) (lines->lists "test.txt"))

;; translated from CL code in http://www.lee-mac.com/listsymdifference.html
(define (list-symmetric-difference l1 l2)
  (append
    (filter-not (lambda (x) (member x l2)) l1)
    (filter-not (lambda (x) (member x l1)) l2)))

(list-symmetric-difference list1 list2)

输出:

'("3" "4" "5" "6")