代码之家  ›  专栏  ›  技术社区  ›  calebeja9

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

  •  1
  • calebeja9  · 技术社区  · 7 年前

    我现在要做的是在一个文本文件中使用两组整数作为参数来执行一个计算两组整数对称差的函数。文本文件的格式是,在第一行有一组数字,每个数字用空格分隔;在第二行有另一组不同的数字,每个数字用空格分隔。例如:

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

    但是当使用读取文件的函数运行helper函数时,我会 #\1#\space#\2#\space#\3#\space#\4#\5#\space#\6#\space#\1#space#\2() 如何使helper函数返回列表而不是字符?

    任何帮助都将不胜感激。 另外,我用的是Racket医生。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Alexis King    7 年前

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