2015-07-19 83 views
0
(define-struct directory (name contents)) 
;A directory is a (make-directory String (list-of files) 
;A file is one of: 
; a * String (containing the name of the file; non-empty and does not contain 
"/" 
;* a Directory 

我在做什么是一个函数,它将一个目录和一个文件名用作字符串。然后该函数应该生成文件路径,每个文件或目录以“/”分隔。计划/球拍中的文件路径/

一个示例目录:

(define a1 (make-directory "a1" (list "a1.pdf" "a1q1.rkt" "a1q2.rkt" "a1q3.rkt"))) 
(define a2 (make-directory "a2" (list "a2.pdf"))) 
(define assns (make-directory "assns" (list a1 a2))) 
(define labs (make-directory "labs" (list "lab01.pdf" "lab02.pdf"))) 
(define final (make-directory "final" empty)) 
(define cs115 (make-directory "cs115" (list assns labs final "style.pdf" "survivial.pdf"))) 

例如

(path cs115 "a2.pdf") 

应该产生

"cs115/assns/a2/a2.pdf" 

我有什么至今:

(define (find dir name) 
    (cond 
    [(string=? (directory-name dir) name) name] 
    [(member? name (directory-contents dir)) 
    (string-append (directory-name dir) "/" name)] 
    [(cons? (directory-contents dir)) 
    (content-list (directory-name dir)(directory-contents dir) name)] 
    )) 


(define (content-list dir-name dir-list name) 
    (cond 
    [(empty? dir-list) 
      (content-list dir-name (rest dir-list) name)] 
    [(equal? (first dir-list) name) 
    (string-append dir-name "/" (first dir-list))] 
    [(directory? (first dir-list)) 
    (find (first dir-list) name)] 
    [else (content-list dir-name (rest dir-list) name)] 
    )) 

问候, 山姆

+0

虽然我不知道我理解你的问题,你想_sounds_功能类似球拍的[构建路径(http://docs.racket-lang.org/reference/Manipulating_Paths.html#%28def ._%28%28quote._〜23〜25kernel%29._build路径%29%29)?同时请记住'apply'和'list *'。 –

+0

我的问题是如何创建一个文件路径从我看到的问题 – Sam

+0

上面创建的目录,所以该函数应该找到所需的名称的文件,在目录树的任何深度,并返回完整路径/它们。如果有多个这样的文件,它是否只需要返回它发现的第一个,或者它们全部?另外:到目前为止您尝试了哪些代码,以及您卡在哪里? –

回答

1

此发现一个文件所需的名称,采用您提供的例如通过测试。

#lang racket/base 

(require racket/match 
     racket/string 
     rackunit) 

(struct directory (name  ;string? 
        contents)) ;(listof (or/c string? directory?)) 

(define a1 (directory "a1" (list "a1.pdf" "a1q1.rkt" "a1q2.rkt" "a1q3.rkt"))) 
(define a2 (directory "a2" (list "a2.pdf"))) 
(define assns (directory "assns" (list a1 a2))) 
(define labs (directory "labs" (list "lab01.pdf" "lab02.pdf"))) 
(define final (directory "final" '())) 
(define cs115 (directory "cs115" (list assns labs final "style.pdf" "survivial.pdf"))) 

;; path-to : directory? string? -> (or/c string? #f) 
(define (path-to dir desired-filename) 
    (let loop ([dirnames (list (directory-name dir))] 
      [contents (directory-contents dir)]) 
    (for/or ([x (in-list contents)]) 
     (match x 
     [(directory dirname contents) (loop (cons dirname dirnames) contents)] 
     [(and fn (== desired-filename)) (string-join (reverse (cons fn dirnames)) "/")] 
     [_        #f])))) 

(check-equal? (path-to cs115 "a2.pdf") 
       "cs115/assns/a2/a2.pdf") 
0

但是我想出了答案,我被告知我的代码不是那么高效。

;;------------------ 
;;Defined Structures 
;;------------------ 

(define-struct directory (name contents)) 
;; A Directory is a (make-directory Str (listof File)) 


;; A File is one of: 
;; * a Str (containing the name of the file; nonempty and does not contain "/") 
;; * a Directory 


;;----------------- 
;;Defined Variables 
;;----------------- 

(define a1 (make-directory "a1" (list "a1.pdf" "a1q1.rkt" 
             "a1q2.rkt" "a1q3.rkt"))) 
(define a2 (make-directory "a2" (list "a2.pdf"))) 
(define assns (make-directory "assns" (list a1 a2))) 
(define labs (make-directory "labs" (list "lab01.pdf" "lab02.pdf"))) 
(define final (make-directory "final" empty)) 
(define cs115 (make-directory "cs115" (list assns labs final 
              "style.pdf" "survival.pdf"))) 

;;-------------------- 
;;Helper Function # 1 
;;--------------------- 

;;(search-dirlist list name) 

;;------- 
;;Purpose 
;;------- 

;;(search-dirlist list name):This function consumes a directroy list 
;;       and searches name (the other consumed 
;;       variable) in that list and produces that 
;;       path 


;;-------- 
;;Contract 
;;-------- 

;;(search-dirlist list name): (listof Files) Str -> Str 



;;-------- 
;;Example 
;;-------- 


(check-expect (search-dirlist (list assns labs final 
            "style.pdf" "survival.pdf") "survival.pdf") 
       "survival.pdf") 
(check-expect (search-dirlist (list assns labs final 
            "style.pdf" "survival.pdf") "survival.pdf") 
       "survival.pdf") 
(check-expect (search-dirlist (list assns labs final 
            "style.pdf" "survival.pdf") "lab01.pdf") 
       "labs/lab01.pdf") 
(check-expect (search-dirlist (list "a1.pdf" "a1q1.rkt" "a1q2.rkt" "a1q3.pdf") "a1q2.rkt") 
       "a1q2.rkt") 



;;-------------------- 
;;Function Head & Body 
;;-------------------- 

(define (search-dirlist dirlist name) 
    (cond 
    [(empty? dirlist) ""] 
    [else 
    (cond 
     [(and (directory? (first dirlist)) 
      (contain-file (first dirlist) name)) 
     (string-append (directory-name (first dirlist)) 
         (cond 
         [(string=? name 
            (directory-name 
            (first dirlist))) ""] 
         [else "/"]) 
         (search-dirlist (directory-contents (first dirlist)) name))] 
     [(and (string? (first dirlist)) 
      (string=? (first dirlist) name)) (first dirlist)] 
     [else (search-dirlist (rest dirlist) name)])])) 


;;----- 
;;Tests 
;;----- 


(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "style.pdf") 
       "style.pdf") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "a2") 
       "assns/a2") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "a1q3.rkt") 
       "assns/a1/a1q3.rkt") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "labs") 
       "labs") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "final") 
       "final") 
(check-expect (search-dirlist (list a1 a2) "a2") 
       "a2") 
(check-expect (search-dirlist (list a1 a2) "a1.pdf") 
       "a1/a1.pdf") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "lab01.pdf") 
       "labs/lab01.pdf") 
(check-expect (search-dirlist (list assns labs final 
           "style.pdf" "survival.pdf") "lab02.pdf") 
       "labs/lab02.pdf") 







;;-------------------- 
;;Helper Function # 2 
;;--------------------- 

;;(contain-file dir name) 

;;------- 
;;Purpose 
;;------- 

;;(contain-file dir name):Consumes a directory "dir" and name 
;;      Check if the name exists in the 
;;      directroy and produces boolean 
;;      accordingly. 


;;-------- 
;;Contract 
;;-------- 

;;(contain-file dir name): Directory Str -> Boolean 

;;-------- 
;;Example 
;;-------- 


(check-expect (contain-file cs115 "style.pdf") true) 
(check-expect (contain-file assns "assns") true) 
(check-expect (contain-file cs115 "lab02.pdf") true) 
(check-expect (contain-file labs "a1q1.rkt") false) 


;;-------------------- 
;;Function Head & Body 
;;-------------------- 

(define (contain-file dir name) 
    (cond 
    [(string=? (directory-name dir) name) true] 
    [(list-contains-file (directory-contents dir) name) true] 
    [else false])) 



;;----- 
;;Tests 
;;----- 


(check-expect (contain-file labs "labs") 
       true) 
(check-expect (contain-file labs "lab01.pdf") 
       true) 
(check-expect (contain-file labs "style.pdf") 
       false) 
(check-expect (contain-file final "final") 
       true) 
(check-expect (contain-file final "a1") 
       false) 
(check-expect (contain-file cs115 "cs115") 
       true) 
(check-expect (contain-file cs115 "assns") 
       true) 
(check-expect (contain-file assns "a2") 
       true) 
(check-expect (contain-file assns "a1q3.rkt") 
       true) 
(check-expect (contain-file assns "a2.pdf") 
       true) 
(check-expect (contain-file assns "labs") 
       false) 
(check-expect (contain-file cs115 "labs") 
       true) 
(check-expect (contain-file cs115 "final") 
       true) 
(check-expect (contain-file cs115 "style.pdf") 
       true) 
(check-expect (contain-file cs115 "survival.pdf") 
       true) 
(check-expect (contain-file cs115 "random-file") 
       false) 





;;-------------------- 
;;Helper Function # 3 
;;--------------------- 

;;(list-contain-file dirlist name) 

;;------- 
;;Purpose 
;;------- 

;;(list-contains-file dirlist name): 


;;-------- 
;;Contract 
;;-------- 

;;(list-contains-file dirlist name): 

;;-------- 
;;Example 
;;-------- 

(check-expect (list-contains-file empty "survival.pdf") false);base case 
(check-expect (list-contains-file (list "a1.pdf" "a1q1.rkt" "a1q2.rkt" "a1q3.rkt") 
            "a1q2.rkt") true);simple case 
(check-expect (list-contains-file (list assns labs final "style.pdf" "survival.pdf") 
            "labs")true);check in a structure(directory name) 
(check-expect (list-contains-file (list a1 a2 labs final) 
            "lab01.pdf") true);check in a structure(directory contents) 



;;-------------------- 
;;Function Head & Body 
;;-------------------- 

(define (list-contains-file dirlist name) 
    (cond 
    [(empty? dirlist) false] 
    [(string? (first dirlist)) 
    (cond 
     [(string=? (first dirlist) name) true] 
     [else (list-contains-file (rest dirlist) name)])] 
    [(directory? (first dirlist)) 
    (cond 
     [(string=? (directory-name (first dirlist)) name) true] 
     [(list-contains-file (directory-contents (first dirlist)) name) true] 
     [else (list-contains-file (rest dirlist) name)])])) 


;;----- 
;;Tests 
;;----- 

(check-expect (list-contains-file (list assns labs final 
            "style.pdf" "survival.pdf") 
           "assns") true) 
(check-expect (list-contains-file (list assns labs final 
            "style.pdf" "survival.pdf") 
           "a1") true) 
(check-expect (list-contains-file (list assns labs final 
            "style.pdf" "survival.pdf") 
           "a1q1.rkt")true) 
(check-expect (list-contains-file (list assns labs final 
            "style.pdf" "survival.pdf") 
           "labs") true) 

(check-expect (list-contains-file (list assns labs final 
            "style.pdf" "survival.pdf") 
           "xyz") false) 
(check-expect (list-contains-file (list a1 a2) "a1.pdf") true) 
(check-expect (list-contains-file (list "a1.pdf" "a1q1.rkt" 
            "a1q2.rkt" "a1q3.rkt") 
           "a1q2.rkt") true) 
(check-expect (list-contains-file (list "lab01.pdf" "lab02.pdf") 
           "lab02.pdf") true) 


;;--------------- 
;;Main Function 
;;--------------- 

;;(find dir name) 

;;------- 
;;Purpose 
;;------- 

;;(find dir name):This function consume a directroy dir and 
;;    a Str name and identifies wheather name is 
;;    is in a sub-directory of file and produces 
;;    the path to the file/subdirectroy, if the 
;;    doesn't exist produce false. 



;;-------- 
;;Contract 
;;-------- 

;;(find dir name) Directory Str -> (Anyof False or Str) 



;;-------- 
;;Example 
;;-------- 

(check-expect (find cs115 "cs115") "cs115") 
(check-expect (find cs115 "final") "cs115/final") 
(check-expect (find cs115 "survival.pdf") "cs115/survival.pdf") 
(check-expect (find cs115 "lab01.pdf") "cs115/labs/lab01.pdf") 
(check-expect (find assns "a1q3.rkt") "assns/a1/a1q3.rkt") 
(check-expect (find labs "a1") false) 

;;-------------------- 
;;Function Head & Body 
;;-------------------- 

(define (find dir name) 
    (cond 
    [(contain-file dir name) (cond 
          [(string=? (directory-name dir) name) 
          (directory-name dir)] 
          [else (string-append 
            (directory-name dir) "/" 
            (search-dirlist (directory-contents dir) name))])] 
    [else false])) 


;;----- 
;;Tests 
;;----- 



(check-expect (find cs115 "assns") "cs115/assns") 
(check-expect (find cs115 "labs") "cs115/labs") 
(check-expect (find cs115 "final") "cs115/final") 
(check-expect (find cs115 "style.pdf") "cs115/style.pdf") 
(check-expect (find cs115 "survival.pdf") "cs115/survival.pdf") 
(check-expect (find cs115 "a1") "cs115/assns/a1") 
(check-expect (find cs115 "a2") "cs115/assns/a2") 
(check-expect (find final "a1.pdf") false) 
(check-expect (find a1 "a2") false) 
(check-expect (find a2 "a1q2.rkt") false) 
(check-expect (find cs115 "random-file") false) 
(check-expect (find cs115 "a2.pdf") "cs115/assns/a2/a2.pdf") 
(check-expect (find cs115 "a1q2.rkt") "cs115/assns/a1/a1q2.rkt") 
(check-expect (find cs115 "lab01.pdf") "cs115/labs/lab01.pdf") 
(check-expect (find assns "assns") "assns") 
(check-expect (find final "final") "final")