2015-07-19 61 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")