我想在Scheme中编写Shift或Caesar密码,但不使用字符串。我想改用一个列表:
(define message '(T H E F O X))
(define k 4)
(define A(char->integer #\A))
(define Z(char->integer #\Z))
(define (cipher message)
(if (empty? message)
'()
(begin
(display ((+ (char->integer (car message)) k))->char)
(cipher (cdr message))
)
))
(define (helper)
(cipher message))
我知道缺少我应该使用模数并与A和Z的限制进行比较的部分,但我的问题是如何将(汽车信息)转换为字符然后转换为整数,所以我可以添加k的值;然后将它从整数转换回char以显示其值。
我找到了基于字符串和地图的解决方案,但是如何只使用列表和上面的转换呢?
提前致谢
答案 0 :(得分:1)
所以我的理解是你想要处理符号。
让我们从序言开始:
(define A (char->integer #\A))
(define Z (char->integer #\Z))
(define MOD (+ Z (- A) 1)) ; 26, used for modulo
MOD
已被添加,因为我们需要获取shift modulo
26的结果。现在我们需要将符号转换为整数并返回的过程:
(define (symbol->integer s)
(char->integer (car (string->list (symbol->string s)))))
(define (integer->symbol i)
(string->symbol (list->string (list (integer->char i)))))
测试:
> (symbol->integer 'A)
65
> (integer->symbol 65)
'A
最后是cipher
程序。我更喜欢将k
作为参数:
(define (cipher message k)
(if (empty? message)
'()
(cons (integer->symbol (+ A (modulo (+ k (- (symbol->integer (car message)) A)) MOD)))
(cipher (cdr message) k))))
测试:
> (cipher '(T H E F O X) 4)
'(X L I J S B)
答案 1 :(得分:1)
这是一个允许列表,符号,字符串和字符的通用版本。请注意,我没有手动编写循环(因为这样做对我来说很痛苦,因为map
很容易获得);欢迎你自己做。
此版本使用SRFI 13(适用于string-map
)和SRFI 26(适用于cut
)。 (如果您手动编写循环,并手动扩展cut
,那么您将能够在普通方案中使用它。)
(require srfi/13 srfi/26) ;; for Racket
(define (caesar x shift)
(cond ((char? x) (caesar-char x shift))
((string? x) (caesar-string x shift))
((symbol? x) (caesar-symbol x shift))
((list? x) (caesar-list x shift))
(else (error "Unknown type" x))))
(define (caesar-char ch shift)
(if (char-alphabetic? ch)
(let* ((ord (char->integer ch))
(lower (modulo ord 32))
(upper (- ord lower)))
(integer->char (+ upper (modulo (+ lower shift) 26))))
ch))
(define (caesar-string str shift)
(string-map (cut caesar-char <> shift) str))
(define (caesar-symbol sym shift)
(string->symbol (caesar-string (symbol->string sym) shift)))
(define (caesar-list lst shift)
(map (cut caesar <> shift) lst))
示例:
> (caesar '(T H E F O X) 4)
'(X L I J S B)
> (caesar '(X L I J S B) 22)
'(T H E F O X)
答案 2 :(得分:0)
你的message
不是由字符组成的。这是一个符号列表。测试一下:
(char? (car '(T H E F O X)))
#f
(symbol? (car '(T H E F O X)))
#t
首先,您需要列出字符列表:
(char? (car '(#\a #\b)))
#t
你的另一个问题是语法。你不能这样写->char
。此外,你有一对额外的parens。
您正在尝试应用char->integer
和k之和的数字。
(display ((+ (char->integer (car message)) k))->char)
这将是一个有效的版本:
(display (integer->char (+ (char->integer (car message)) k)))
答案 3 :(得分:0)
symbol->string
和string-append
创建一个消息列表字符串。string-ref
和string->symbol
将结果作为列表。