Проанализируйте список в схеме и получите сумму всех чисел

#list #sum #scheme

#Список #сумма #схема

Вопрос:

Итак, мне нужно написать рекурсивное решение, которое может просматривать каталог и подкаталог списка и суммировать размеры файлов. У меня нулевой опыт работы со схемой, и мой профессор мне не отвечает. Я пробовал несколько разных попыток, но все они заканчивались ошибками. Если бы кто-нибудь мог мне помочь, я был бы очень признателен, потому что у меня осталось не так много времени, чтобы разобраться с этим заданием.

 (define disk '("D" "main"
(
    ("F" "file1.txt" (30))
    ("F" "file2.txt" (11))

    ("D" "sub1"
    (
        ( "F" "file1.txt" (1234))
        ( "F" "file2.txt" (2345))
        ( "F" "file3.txt" (3456))
    )
    )
    ("D" "sub2"
    (
        ( "F" "file1.txt" (1234))
        ( "F" "file2.txt" (2345))
        ( "F" "file3.txt" (3456))
    )
    )
)
)
)

(define (getEnd n)
    (let ((n 1)))
    (let ((m 0)))
    (member 3 '(disk.n))
    (  m (getEnd (  n 1)))

)
  

Когда я запускаю код, я всегда получаю эту ошибку:

           Ill-formed special form: (let (...))
  

Я пытался использовать оператор let вне функции, но он по-прежнему не работает, потому что я понятия не имею, как работает схема. Я обратился к своим одноклассникам, и они, похоже, тоже не могут понять это.

Любая помощь будет оценена, спасибо!

Комментарии:

1. Проверьте в документации, мы используем не так let — синтаксис неверен

2. Этот код больше похож на код C, чем на код Scheme.

Ответ №1:

A let — это локальная связанная переменная, которая существует в теле или форме. То есть:

 (let ((n 1))           ; bind one variable 1
  (display (  n n))    ; use n for something
  )                    ; end of let. `n` no longer exist.
  

Поскольку у вас есть тег java, диалект C, это то же самое, что и это:

 {
  int n = 1;
  System.out.println(n   n); // use n for something
}
// end of block. n no longer exist
  

В вашем коде у вас нет выражений, использующих привязку, и если бы это было разрешено, это был бы мертвый код, например:

 {
  int n = 1;
}
// end of block. n no longer exist
  

Код (member 3 '(disk.n)) всегда #f , поскольку '(disk.n) представляет собой список с одним символом, disk.n и (equal? 3 'disk.n) ; ==> #f

Последняя строка ( m (getEnd ( n 1)) выполняет безусловную рекурсию путем увеличения n . Он не суммирует никакие числовые значения из структуры.

вопросы

Кажется, вы можете проверить, является ли список файлом или каталогом, посмотрев на первый элемент либо «F», либо «D», Таким образом, вы могли бы сделать:

 (define (file? lst)
  ; todo: implement
  )

(file? '("F" "file1.txt" (1234))) ; ==> #t
(file? '("D" ())                  ; ==> #f
  

Вы можете получить список файлов, проверив третий элемент каталога:

 (define (directory-elements dir)
  ; todo: implement
  )

(directory-elements '("D" "D" (("F" "F1" (1234)) ("F" "F2" (2345)))))
; ==> (("F" "F1" (1234)) ("F" "F2" (2345)))
  

Вы можете создать процедуру, которая получает размер файла:

 (define (file-size file)
  ; todo: implement
  )

(file-size '("F" "F1" (1234)))
; ==> 1234
  

Теперь вы можете создать свою целевую процедуру, используя приведенные выше:

 (define (size file-or-dir)
  (if (file? file-or-dir)
      (file-size file-or-dir)
      (directory-elements-size (directory-elements file-or-dir)))

(size '("F" "F1" (1234))) ; ==> 1234
(size '("D" "D" (("F" "F1" (1234)) ("F" "F2" (2345))))) ; ==> 3579
  

Вы пропали directory-elements-size без вести . Это можно сделать с помощью рекурсии:

 (define (directory-elements-size lst)
  (if (null? lst)
      <???>                                  ; size of an empty directory
      (  (size <????>)                       ; add the size of first file/dir
         (directory-elements-size <????>)))) ; with the size of the rest of the elements
  

Вот так. У вас должно быть более чем достаточно, чтобы начать работу.