文字列を 26 進数に変換してから、元に戻す必要があります。
私の現在のコードは次のとおりです。
(define (26-ary-word s)
(let ([len (string-length s)])
(let f ([n 0]
[acc (+
(- (char->integer (string-ref s 0)) 97)
1)]) ; adding 1 so that all strings start with 'b'
(if (< n len)
(f (add1 n) (+ (* acc 26) (- (char->integer (string-ref s n)) 97)))
acc))))
(define (word-ary-26 n)
(let f ([n (/ (- n (modulo n 26)) 26)]
[acc (cons (integer->char (+ (modulo n 26) 97)) '())])
(if (> n 0)
(f (/ (- n (modulo n 26)) 26) (cons (integer->char (+ (modulo n 26) 97)) acc))
(list->string (cdr acc))))) ; remove "b" from front of string
最初に acc に 1 を追加し、最後の "b" を削除します。これは"a" - 97
、26 を掛けても 0 のままだからです。
これはすでに醜いですが、機能しません。"z" は最初の位置 ( 26^2
) にある場合は "701" として記録され、"az" に変換されます。
最初の文字が z かどうかを検出する if 句をもう 1 つ追加できますが、それは本当に見苦しいです。この問題を回避する方法はありますか?
(if (and (= n 0) (= acc 26))
(f (add1 n) 51)
(f (add1 n) (+ (* acc 26) (- (char->integer (string-ref s n)) 97))))
これは、私が使用しなければならなかった醜いエッジ ケース処理コードです。