Вот моя реализация. Обратите внимание, что вам необходимо загрузить SRFI 1, который обеспечивает unfold-right
:
(define letters "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
(define (number->letters num)
(unfold-right negative?
(lambda (i) (string-ref letters (remainder i 26)))
(lambda (i) (- (quotient i 26) 1))
num))
(define (number->tag num)
(list->string (cons #\M (number->letters num))))
Примеры:
> (number->tag 0)
"MA"
> (number->tag 18277)
"MZZZ"
> (number->tag 18278)
"MAAAA"
ОП попросил объяснения того, что делает код. Таким образом, при понимании того, что ОП уже понимает алгоритм (поскольку они уже связаны с ним), то, что в принципе осталось, - это операция разворачивания.
Сложите и разворачивайте, чтобы объяснить, и я не хочу срывать это сообщение, объясняя их, но можно «развернуть» разворачивание в эквивалентный цикл (используя те же имена переменных, что и SRFI 1 reference implementation из unfold-right
), чтобы выразить то, что происходит:
(define (number->letters num)
(let lp ((seed num) (ans '()))
(if (negative? seed)
ans
(lp (- (quotient seed 26) 1)
(cons (string-ref letters (remainder seed 26)) ans)))))
в основном, это создает список, справа налево, используя (string-ref letters (remainder seed 26))
каждой итерации (где seed
является num
в начальной итерации). Значение seed
затем обновляется до (- (quotient seed 26) 1)
для следующей итерации. Список останавливается, когда верно значение (negative? seed)
.
Тогда вы можете спросить, почему вместо цикла нужно использовать развертку. В принципе, в функциональном программировании, когда «концепция» может быть выражена в терминах более высокого уровня (например, для каждого, на карте, на фильтрацию, сворачивание или разворачивание), использование этих терминов помогает другим программистам понять, что делает код. Это немного напоминает «шаблоны проектирования» (как это обычно используется в объектно-ориентированном программировании) в контексте функционального программирования. :-)
Спасибо! Но не могли бы вы предоставить мне объяснение того, что на самом деле делает код? –
Я добавил многообещающее объяснение. Лемм знает, есть ли что-то еще, что вам нужно объяснить. :-) –
У меня получилось :) Однако я хотел бы улучшить свое понимание складок и разворачиваться и на карте. Не могли бы вы предоставить мне некоторые ссылки, где есть простое объяснение? Я новичок в функциональном программировании. –