Имитация бинарного сложения - DrRacket Intermediate Студент с лямбдой - PullRequest
0 голосов
/ 06 ноября 2019

Как следует из названия, я студент колледжа, использующий DrRacket с языком Intermediate With Lambda . Мое назначение - это алгоритм, который, учитывая строку, содержащую двоичное число, отображает в качестве вывода следующее число, работая только с двоичным представлением (таким образом, не преобразуя в десятичное число, добавляя +1 и повторно преобразуя в двоичное). Я пропустил первые три недели моего курса, так как я был за границей, и теперь я пытаюсь наверстать упущенное, и, насколько я понял, сейчас главная цель профессора - заставить нас заниматься рекурсией (более того, мыне разрешается использовать списки или циклы, подобные тем, которые возможны с do , только функции, которые определены через лямбда-выражения).
Я сделал несколько попыток при назначении, и теперь мой код выглядит следующим образом:

; function called by the user

(define bin-succ
  (lambda (bin)    ; not-empty string of "0"s and "1"s
    (let ( (k (- (string-length bin) 1)) (post (make-string 0)) )
      (position bin k post)
      )
    )
  )

; actual recursive function of the code: it searches from the least significant
; bit to the most significant bit if there is any "0" in the string

(define position
  (lambda (bin k post)
    (cond ( (= k -1)
            (string-append "1" post) )
          ( (char=? (string-ref bin k) #\0)
            (string-append (substring bin 0 k) "1" post) )
          ( (char=? (string-ref bin k) #\1)
            ((position bin (- k 1) post)
            (string-append "0" post)) )
          )
    )
  )

В данный момент алгоритм работает с числами, последняя цифра которых равна 0, например 0, 10, 11010 и т. Д., Но когда я объявляю в качестве входных данных число, заканчивающееся на 1,Программа выделяет последнюю часть кода, в частности

((position bin (- k 1) post)
            (string-append "0" post))

и возвращает ошибку:

function call: expected a function after the open parenthesis, but received "11"

Я пытался использовать begin для создания списка выражений в другой функции, вызываемой третьим случаем cond , который будет повторно вызывать функцию position , таким образом делая алгоритм снова рекурсивным,но не повезло, так как этода, begin не является определенной функцией.
Возможно, я упускаю что-то очень простое (в основном из-за пропущенных вводных классов), или я мог принять эту проблему с неправильным мышлением,но в любом случае я застрял, и я ценю любой полезный вклад.
Просто последний вопрос: также использование else в последнем случае cond не принято, можеткто-нибудь объяснит мне почему? Тот факт, что DrRacket использует несколько языков, меня сильно озадачивает, так как большая часть документации в Интернете не работает с моими текущими настройками.

1 Ответ

1 голос
/ 06 ноября 2019

Может быть, вы до сих пор просматривали документацию Ракетка , а не ISL + (Средний студент с лямбдой)? См. https://docs.racket -lang.org / htdp-langs / промежуточный-lam.html документацию по ISL +. Нажатие f1 на термин из DrRacket приведет вас к документации в контексте языка, который вы используете.

((position bin (- k 1) post)
            (string-append "0" post))

Это функциональное приложение. Вы пытаетесь применить (в качестве аргумента): (string-append "0" post) к функции (position bin (- k 1) post). Однако position возвращает String .

Вы можете просто передать новый пост на рекурсивный вызов. И вы можете использовать else в последнем предложении тоже. Это рабочий код:

; String -> String
(define (bin-succ bin)
  (position bin (- (string-length bin) 1) ""))

; String Number String -> String
(define (position bin k post)
  (cond  [(= k -1)
          (string-append "1" post)]
         [(char=? (string-ref bin k) #\0)
          (string-append (substring bin 0 k) "1" post)]
         [else
          (position bin (- k 1) (string-append "0" post))]))

Более чистое решение было бы, чтобы не имел счетчик:

(define (bin-succ bin)
  (cond [(string=? bin "1") "10"]
        [(string=? (last bin) "0") (string-append (all-but-last bin) "1")]
        [else (string-append (bin-succ (all-but-last bin)) "0")]))

(define (last str)
  (substring str (sub1 (string-length str)) (string-length str)))

(define (all-but-last str)
  (substring str 0 (sub1 (string-length str))))
...