Scheme 在“a”中反转简单函数;“创造性”;打球

Scheme 在“a”中反转简单函数;“创造性”;打球,scheme,racket,reverse,Scheme,Racket,Reverse,我需要一些帮助:D 我编写了以下过程,将字符串转换为数字列表: (define (string->encodeable string) (map convert-to-base-four (map string->int (explode string)))) 我需要一个函数,它的作用正好相反。换句话说,获取以4为基数的数字列表,将其转换为以10为基数,然后创建一个字符串。是否有一种“创造性”的方法来逆转我的功能,或者我必须重新编写每一个相反的步骤。非常感谢您的帮助。取决于您

我需要一些帮助:D

我编写了以下过程,将字符串转换为数字列表:

(define (string->encodeable string)
   (map convert-to-base-four (map string->int (explode string))))
我需要一个函数,它的作用正好相反。换句话说,获取以4为基数的数字列表,将其转换为以10为基数,然后创建一个字符串。是否有一种“创造性”的方法来逆转我的功能,或者我必须重新编写每一个相反的步骤。非常感谢您的帮助。

取决于您如何定义“创造性”。在球拍中,你可以这样做:

(define (f lst)
  (number->string
   (for/fold ([r 0]) ([i (in-list lst)])
     (+ i (* r 4)))))
然后


使用

它在
#lang racket
中的工作原理相同,但是您
(需要srfi/1)


PS:我不完全确定从10进制到4进制的转换是否是最好的解决方案。想象一下数字
95
,它应该变成
(13)
。我会用SRFI-1中的
右展开
来完成

你正在寻找的关系被称为

这里的其他答案用折叠来证明这一点,但在你的水平上,我认为你应该自己做这件事——或者至少在你更熟悉这门语言之前

#lang racket

(define (base10 ns)
  (let loop ((ns ns) (acc 0))
    (if (empty? ns)
        acc
        (loop (cdr ns) (+ (car ns)
                          (* 4 acc))))))

(displayln (base10 '(3 0)))               ; 12
(displayln (base10 '(3 1)))               ; 13
(displayln (base10 '(3 2)))               ; 14
(displayln (base10 '(3 3)))               ; 15
(displayln (base10 '(1 0 0)))             ; 16
(displayln (base10 '(1 3 2 0 2 1 0 0 0))) ; 123456

@提到了内奥米克的回答。当你构造一个同构时,你在一起构造一个函数和它的逆。通过组合和连接同构,可以“同时”构造两个方向

此代码包含将基数为4的列表转换为数字并再次转换所需的所有信息。(此处的基4列表按最低有效位到最高有效位的顺序排列。这与正常方向相反,但这没关系,可以在外部固定。)

第一个cond案例将空映射为零,然后再次映射

第二种情况将
(cons r q)
映射到
(+(*4 q)r)
,然后再映射回来,但是在列表和数字之间递归地转换
q

正如cons单元格可以使用
first
rest
拆分一样,正数也可以拆分为其“余数-wrt-4”和“商-wrt-4”。由于余数是固定大小,商是任意大小,
余数
类似于
第一个
类似于
其余

第一个
余数
不需要相互转换,因此第一个
iso join
子句使用了
iso标识
,即不起任何作用的同构

[first  iso-identity       (curryr remainder 4)]
但是,
rest
确实需要转换。其余的是一个以最低至最高有效顺序排列的以4位为基数的数字列表,商是与之对应的数字。它们之间的转换是
iso-base4->number

[rest   iso-base4->number  (curryr quotient 4)]

如果您对这些同构形式(如
iso const
iso cond
、和
iso join
)的定义感兴趣,则包含本示例所需的所有内容。

我理解您的观点和创造性思维,但我对for/fold不太熟悉。非常感谢你的努力,这正是我想要的。非常感谢你,亲爱的朋友。
;; Converts between a base 4 list of digits (least significant first, most
;; significant last) and a number.
(define iso-base4->number
  (iso-lazy
   (iso-cond

     ;; an iso-cond clause has an A-side question, an A-to-B isomorphism,
     ;; and a B-side question. Here the A-side is empty and the B-side is 
     ;; zero.
     [empty?  (iso-const '() 0)  zero?]

     ;; Here the A-side is a cons, and the B-side is a positive number.
     [cons?
      (iso-join
        cons
        (λ (r q) (+ (* 4 q) r))
        [first  iso-identity       (curryr remainder 4)]
        [rest   iso-base4->number  (curryr quotient 4)])
      positive?])))
[first  iso-identity       (curryr remainder 4)]
[rest   iso-base4->number  (curryr quotient 4)]