方案中的可变数据返回对,其中右侧元素是匹配条件的最大后缀

发布于 2024-11-16 00:20:06 字数 629 浏览 2 评论 0原文

我有这个定义“排序左侧列表”,它是根据每对的左侧元素排序的对列表,左侧元素必须是非负整数,并且右组件可以是任何类型的值

我必须编写一个过程 mkjump ,它将非负整数的排序列表作为参数, sorted-lst = (x1 ... xn) 并返回左排序列表: sort left list = ((x1.y1)...(xn.yn)) 这样:yi 是 sort left list 的最大后缀, ((xj . yj)...(xn . yn)) 其中对于所有 xk,xk>(xi)^2。例如:

   >(define lst (list 2 3 4 15 16 17))
   >(mkjump lst)
   >lst
    ( (2 (15) (16) (17))
    (3 (15) (16) (17))
    (4 (17))
    (15)
    (16)
    (17) )

res 中的第 6 个元素是 (x6 . y6),其中 x6=17 且 y6=null。 res 中的第三个元素是 (x3 . y3), 其中x3=4,y3是包含(x6.y6)的列表,它是res的最大后缀,其中xk>(xi)^2 for all xk

怎么写呢?

I have this definition "sort left list" which is a list of pairs sorted according to the left element of each pair the left element must be a non-negative integer and the right component may be a value of any type

I have to write a procedure mkjump which takes as an argument a sorted list of non-negative integers,
sorted-lst = (x1 ... xn) and returns a left-sorted list:
sort left list = ((x1.y1)...(xn.yn)) such that: yi is the largest suffix of sort left list,
((xj . yj)...(xn . yn)) in which xk>(xi)^2 for all xk. For example:

   >(define lst (list 2 3 4 15 16 17))
   >(mkjump lst)
   >lst
    ( (2 (15) (16) (17))
    (3 (15) (16) (17))
    (4 (17))
    (15)
    (16)
    (17) )

The 6th element in res is (x6 . y6) where x6=17 and y6=null. The 3rd element in res is (x3 . y3),
where x3=4 and y3 is the list containing (x6 . y6), which is the largest suffix of res in which xk>(xi)^2
for all xk

How to write it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初吻给了烟 2024-11-23 00:20:07

我在麻省理工学院的计划中做到了这一点,希望它也适用于球拍。我假设您实际上不必使用突变,因为您的示例并不依赖于它。

(define (square x) (* x x))

(define (mkjump lst)
  (if (null? lst)
      '()
      (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
        (mkjump (cdr lst)))))

(define (wrapper item lst)
  (modmap (lambda (x) 
         (if (< (square item) x)
             (list x)
             #f))
         lst))

(define (modmap proc lst)
  (cond ((null? lst) '())
        ((proc (car lst)) (cons (proc (car lst)) (modmap proc (cdr lst))))
        (else (modmap proc (cdr lst))))) 

I did this in MIT-scheme, hopefully it works in racket too. I'm assuming you don't actually have to use mutation, given that your example doesn't depend upon it.

(define (square x) (* x x))

(define (mkjump lst)
  (if (null? lst)
      '()
      (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
        (mkjump (cdr lst)))))

(define (wrapper item lst)
  (modmap (lambda (x) 
         (if (< (square item) x)
             (list x)
             #f))
         lst))

(define (modmap proc lst)
  (cond ((null? lst) '())
        ((proc (car lst)) (cons (proc (car lst)) (modmap proc (cdr lst))))
        (else (modmap proc (cdr lst))))) 
尤怨 2024-11-23 00:20:06

如前所述,您不需要可变状态来完成您的工作。但是,如果您确实想使用它们,您可以轻松更改 Keen 的解决方案以获得您想要的。首先你必须以尾递归的方式翻译他的代码。你可以从mkjump开始

(define (mkjump lst) (reverse (mkjump-tr lst '())))

(define (mkjump-tr lst sol)
  (if (null? lst)
      sol
      (mkjump-tr (cdr lst) 
                 (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) ))

,然后你可以改变modmap

(define (modmap proc lst) (reverse (modmap-tr proc lst '())))

(define (modmap-tr proc lst sol)
  (cond ((null? lst) sol)
        ((proc (car lst)) (modmap-tr proc 
                                     (cdr lst) 
                                     (cons (proc (car lst)) sol) ))
        (else (modmap-tr proc (cdr lst) sol)))) 

尾递归mkjump-tr将在迭代过程中被翻译。这是因为它可以被视为一个 while 循环。这使您能够使用 do 构造创建此循环。这样 mkjump-tr 可以写成

(define (mkjump-tr lst sol)
  (do ((lst lst (cdr lst))
       (sol sol (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) )
    ((null? lst) sol)
    ))

modmap-tr 可以翻译为

(define (modmap-tr proc lst sol)
  (do ((lst lst (cdr lst))
       (sol sol (if (proc (car lst)) (cons (proc (car lst)) sol) sol)) )
    ((null? lst) sol)
    ))

但是由于我们没有递归形式,所以我们可以直接写这些 do< /code> 位于之前的函数 mkjumpmodmap 中。所以我们

(define (mkjump lst) 
  (do ((lst lst (cdr lst))
       (sol '() (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) )
    ((null? lst) (reverse sol))
    ))

(define (modmap proc lst) 
  (do ((lst lst (cdr lst))
       (sol '() (if (proc (car lst)) (cons (proc (car lst)) sol) sol)) )
    ((null? lst) (reverse sol))
    ))

可以看到一些细微的变化:reversesol 之前添加,并且 sol 在两种情况下都由空列表初始化。

最后,如果您确实想在某处看到一些set!,只需通过破坏do循环结构来添加它们即可。这是mkjump的解决方案,

(define (mkjump lst)
  (let ((elt 'undefined)
        (lst lst)
        (sol '()))
  (do () 
    ((null? lst) (reverse sol))
    (set! elt (car lst))
    (set! lst (cdr lst))
    (set! sol (cons (cons elt (wrapper elt lst)) sol))
    )))

我会让你改变modmap。最后这两个修改混淆了算法背后的想法。因此,以这种方式改变它们是一个坏主意,因为它们不会改进任何东西。然而,第一个修改可能是个好主意。所以我建议你保留第一次修改。

这是你所期望的吗?

As stated previously you do not need mutable state to do your job. However, if you really want to use them you can easily change Keen's solution to get what you want. First you have to translate his code in a tail recursive way. You can begin with mkjump

(define (mkjump lst) (reverse (mkjump-tr lst '())))

(define (mkjump-tr lst sol)
  (if (null? lst)
      sol
      (mkjump-tr (cdr lst) 
                 (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) ))

Then you can change modmap

(define (modmap proc lst) (reverse (modmap-tr proc lst '())))

(define (modmap-tr proc lst sol)
  (cond ((null? lst) sol)
        ((proc (car lst)) (modmap-tr proc 
                                     (cdr lst) 
                                     (cons (proc (car lst)) sol) ))
        (else (modmap-tr proc (cdr lst) sol)))) 

The tail recursive mkjump-tr will be translated in an iterative process. This is because it can be seen as a while loop. This enable you to create this loop with the do construction. This way mkjump-tr can be write as

(define (mkjump-tr lst sol)
  (do ((lst lst (cdr lst))
       (sol sol (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) )
    ((null? lst) sol)
    ))

and modmap-tr can be translated as

(define (modmap-tr proc lst sol)
  (do ((lst lst (cdr lst))
       (sol sol (if (proc (car lst)) (cons (proc (car lst)) sol) sol)) )
    ((null? lst) sol)
    ))

But since we do not have recursive form, we can directly write these do's in the former functions mkjump and modmap. So we get

(define (mkjump lst) 
  (do ((lst lst (cdr lst))
       (sol '() (cons (cons (car lst) (wrapper (car lst) (cdr lst)))
                       sol)) )
    ((null? lst) (reverse sol))
    ))

(define (modmap proc lst) 
  (do ((lst lst (cdr lst))
       (sol '() (if (proc (car lst)) (cons (proc (car lst)) sol) sol)) )
    ((null? lst) (reverse sol))
    ))

You could see some slight changes: reverse is added before sol and sol is initialize by the empty list in both case.

Finally, if you really want to see some set! somewhere, just add them by breaking the do-loop construction. Here is the solution for mkjump

(define (mkjump lst)
  (let ((elt 'undefined)
        (lst lst)
        (sol '()))
  (do () 
    ((null? lst) (reverse sol))
    (set! elt (car lst))
    (set! lst (cdr lst))
    (set! sol (cons (cons elt (wrapper elt lst)) sol))
    )))

I will let you change modmap. These two last modifications obfuscate the idea behind the algorithm. Therefore, it is a bad idea to change them this way, since they will not improve anything. The first modification can be a good idea however. So I will suggest you to keep the first modification.

Is this what have you expected ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文