转换为球拍(方案)

Convert to Racket(Scheme)

我在 python 上有有效的代码。我是DRrACKET的新手,如何将其翻译成DRrACKET。 我正在努力编写生成准确结果的 DRrACKET 代码。

非常感谢您的帮助。

# python program to find the length of the largest subarray which has all contiguous elements 

def length_sub_(arr, n):
max_len = 1
for i in range(0,n - 1):

    myset = set()
    myset.add(arr[i])

    # Initialize max and min in
    # current subarray
    mn = arr[i]
    mx = arr[i]
    for j in range(i + 1,n):

        # If current element is already
        # in hash set, then this subarray
        # cannot contain contiguous elements
        if arr[j] in myset:
            break


        # Else add current element to hash
        # set and update min, max if required.
        myset.add(arr[j])
        mn = min(mn, arr[j])
        mx = max(mx, arr[j])

        # We have already checked for
        # duplicates, now check for other
        #property and update max_len
        # if needed
        if mx - mn == j - i:
            max_len = max(max_len, mx - mn + 1)

 return max_len # Return result



arr = [6, 1, 1, 10, 10, 111, 100]
print("Length of the longest contiguous subarray is : ",
                            length_sub_(arr,len(arr)))

预期输出:

最长连续子数组的长度为:2

我的DRrACKET开始 我已经实现了一些自定义函数,这些函数充当期望输出的辅助函数

 #lang racket
 ;custom function to check if an elemet is contained in a list
 (define custom-member
  (lambda (x los)
    (cond
     ((null? los) #f)
      ((= x (car los)) #t)
      (else (custom-member x (cdr los))))))

    ;checks if all the elements in the set are unique
    (define are-all-unique 
      (lambda (v)
       (if (not (null? v))
        (and (not (custom-member (car v) (cdr v)))
         (are-all-unique (cdr v)))
         #t)))
   ;reverses the list
    (define (reverse-helper lst ACC)
     (if (null? last)
     acc
  (reverse-helper (cdr lst) (cons (car lst) ACC))))

 (define (custom-reverse last)
   (reverse-helper lst '()))

(define (unique-elements last)
  (let loop ((lst (flatten lst)) (res '()))
  (if (empty? last)
     (custom-reverse res)
     (let ((c (car lst)))
      (loop (cdr lst) (if (custom-member c res) res (cons c     res)))))))


; define the length of the list
 (define custom-length
  (lambda (list)
   (if (null? list)
     0
    (+ 1 (custom-length (cdr list))))))


;performs the actual list check
(define max-contiguous-repeated-length
 (lambda (L)
  (cond
   [(null? L) 0]
    [else (cond
           [(are-all-unique L) 1]
           [else (custom-length (unique-elements L))])]
    )
   ))

  (max-contiguous-repeated-length '(1 1 2 1 2 1 2))

尝试“翻译”Python 可能不是学习 Scheme/Racket 的最佳方法;尝试从这个开始 存根,并跟随球拍 How To Design Functions 设计配方:

(define (max-repeated-length lon) ;; ListOfNumber -> Natural
  ;; produce length of longest section of lon with equal elements
  0)

(check-expect (max-repeated-length '()) 0)

; (check-expect (max-repeated-length '(6 1 1 10 10 111 100)) 2)

设计方法的下一步是选择一个模板, 用适合所需功能的标识符替换通用标识符, 并添加示例以指导模板中占位符替换的编码。

带有列表参数的函数的最简单模板是“自然递归”:

(define (fn lox) ;; ListOfX -> Y                  ; *template*: (for fn with list argument)
  ;; produce a Y from lox using natural recursion ;
  (cond                                           ;
    [(empty? lox) ... ]                           ; (... = "base case value" ;; Y )
    [else (...                                    ; (... = "inventory fn(s)" ;; X Y -> Y )
           (first lox) (fn (rest lox))) ]))       ; [1]

针对此问题进行编辑,这将是:

(define (max-repeated-length lon) ;; ListOfNumber -> Natural
  ;; produce length of longest section of lon with equal elements
  (cond
    [(empty? lon) 0 ]
    [else (...
           (first lon) (max-repeated-length (rest lon))) ]))

所以这就是可以开始详细说明的方式 (define max-repeated-length (lambda (L) (cond ) ) )

示例可以是:

(check-expect (max-repeated-length '(1)) 1)
(check-expect (max-repeated-length '(1 2)) 1)
(check-expect (max-repeated-length '(1 2 2)) 2)
(check-expect (max-repeated-length '(1 2 2 2 3 3)) 3)

上面的模板是一个开始(第一个测试通过),但可能不清楚如何 开始编写 ... 的替换代码。 How to Design Functions 有相关的设计方法和模板,但这个答案不会明确使用它们。

继续使用自然递归模板的问题是结果是 产生取决于 lon 内重复部分的长度。有了编程经验, 可以看到当前值被重复(cur-val), 当前重复的 length-so-far (cur-lsf),以及 maximum-so-far 重复长度 (max-lsf),需要生成所需的值。 max-repeated-length 不包含这些值,因此引入一个函数 它们作为参数 ( (max-repeats lon cur-val cur-lsf max-lsf) ),并从 max-repeated-length 调用它,它变成:

(define (max-repeated-length lon) ;; ListOfNumber -> Natural
  ;; produce length of longest section of lon with equal elements
  (cond
    [(empty? lon) 0]
    [else (max-repeats (rest lon) (first lon) 1 1) ]))

max-repeats 的参数是从 cur-val(first lon) 开始的事实推导出来的,等等)

max-repeats存根,带有签名目的,存根value 现在可以写了, 一些测试:

(define (max-repeats lon cur-val cur-lsf max-lsf) ;; ListOfNumber Number Natural Natural -> Natural
  ;; produce max-so-far of lengths of sections of lon with equal elements
  max-lsf)
  
(check-expect (max-repeats '() 1 1 1) 1)
(check-expect (max-repeats '(2) 1 1 1) 1)
(check-expect (max-repeats '(2) 2 1 1) 2)

max-repeats 可以像自然递归一样进行模板化,并在发现重复时附加条件:

(define (max-repeats lon cur-val cur-lsf max-lsf) ;; ListOfNumber Number Natural Natural -> Natural
  ;; produce max-so-far of lengths of sections of lon with equal elements
  (cond
    [(empty? lon) max-lsf ]
    [(= (first lon) cur-val) ... ]
    [else ... ]))

(占位符将替换为根据参数构建的表格, (first lon)(max-repeats (rest lon) ... )(add1 cur-lsf))

else ... 占位符很简单:它是(可能的)新重复的开始,就像 max-repeated-length 中的调用但保留 max-lsf 值。看例子, 可以看到完整的 max-repeats,和以前一样 max-repeated-length, 另一个测试是:

(define (max-repeats lon cur-val cur-lsf max-lsf) ;; ListOfNumber Number Natural Natural -> Natural
  ;; produce max-so-far of lengths of sections of lon with equal elements
  (cond
    [(empty? lon) max-lsf ]
    [(= (first lon) cur-val)
     (max-repeats (rest lon) cur-val (add1 cur-lsf) (max max-lsf (add1 cur-lsf))) ]
    [else (max-repeats (rest lon) (first lon) 1 max-lsf) ]))

(define (max-repeated-length lon) ;; ListOfNumber -> Natural
  ;; produce length of longest section of lon with equal elements
  (cond
    [(empty? lon) 0]
    [else (max-repeats (rest lon) (first lon) 1 1) ]))

(check-expect (max-repeated-length '(1 2 3 3 4 5 5 5 6 7 7 8)) 3)

所以,运行再次检查:

Welcome to DrRacket, version 8.4 [cs].
Language: Beginning Student with List Abbreviations [custom].
Teachpack: batch-io.rkt.
All 10 tests passed!
> 

请注意,如果 = 替换为 equal? [2],则 max-repeated-length 可能适用于 多种 Scheme 对象的列表,例如: (max-repeated-length '(a b b b c c)) ==> 3 (max-repeated-length '(1 '(2 3) '(2 3) '(2 3) 4 4)) ==> 3

[1]:模板 (... (first lox) (fn (rest lox))) 可能表示包含 (first lox)(rest lox)

的更详细的形式

[2]:(其他等价谓词可用)

Scheme 的一个好处是它鼓励您寻找优雅的解决方案,而不是问题中令人毛骨悚然的恐怖,因为知道优雅的解决方案通常也是有效的解决方案。

所以,我认为这显然是一个家庭作业问题,我真的不想帮助人们作弊,这里有一个优雅的解决方案 Python.在 Python 中,这可能效率不高,尤其是对于长数组。变成 Racket 既是显而易见的解决方案又是高效的。

def longest_contiguous(a):
    l = len(a)
    def loc(i, current, this, best):
        # i is current index, current is the element in the current
        # run, this is the length of the current run, best is the
        # length of the longest run.
        if i == l:              # we're done
            return best if best > this else this
        elif a[i] == current:   # in a run
            return loc(i + 1, current, this + 1, best)
        else:                   # new run
            return loc(i + 1, a[i], 1, best if best > this else this)
    return loc(0, a[0], 1, 1) if l > 0 else 0

这里是 Racket 中一个非常优雅的解决方案:以这样的方式构建,同样,它可能无法作为作业提交。这将适用于向量和列表,实际上还有很多其他的东西。除了最长连续序列的长度外,它还会告诉您该序列从哪里开始。

(require racket/stream
         racket/generic)

(define-generics to-stream
  ;; Turn something into a stream in a way which could be extended
  (->stream to-stream)
  #:fast-defaults
  ((stream?
    (define ->stream identity))
   (sequence?
    (define ->stream sequence->stream))))

(define (length-of-longest-contiguous-subthing thing
                                               #:same? (same? eqv?)
                                               #:count-from (count-from 0))
  (define s (->stream thing))
  (if (stream-empty? s)
      (values 0 count-from)
      (let los ([st (stream-rest s)]
                [current (stream-first s)]
                [count (+ count-from 1)]
                [this 1]
                [this-start 0]
                [best 0]
                [best-start 0])
        (cond
          [(stream-empty? st)
           (if (> this best)
               (values this this-start)
               (values best best-start))]
          [(same? (stream-first st) current)
           (los (stream-rest st) current (+ count 1)
                (+ this 1) this-start
                best best-start)]
          [else
           (if (> this best)
               (los (stream-rest st)
                    (stream-first st) (+ count 1)
                    1 count
                    this this-start)
               (los (stream-rest st)
                    (stream-first st) (+ count 1)
                    1 count
                    best best-start))]))))

现在,例如:

> (length-of-longest-contiguous-subthing '(1 2 3 4 4 5 6 6 6 7))
3
6

最长的连续子序列是 3 个元素 log,从第 6 个元素开始。

还有:

> (call-with-input-file
   "/tmp/x"
   (λ (p)
     (length-of-longest-contiguous-subthing (in-lines p)
                                            #:same? string=?
                                            #:count-from 1)))

/tmp/x中相同行的最长序列为2,从第2行开始,从1开始数。

好的,你想要的,

[6, 1, 1, 10, 10, 111, 100] => 2
[6, 1, 1, 1, 100, 111, 100] => 3
[6, 10, 10, 20, 10, 10, 10] => 3

因为

[[6], [1, 1], [10, 10], [111], [100]] => [1,2,2,1,1] => 2
[[6], [1, 1, 1], [100], [111], [100]] => [1,3,1,1,1] => 3
[[6], [10, 10], [20], [10, 10, 10]]   => [1,2,1,3]   => 3

因此,采用 higher-level 观点,我们

(define (length-longest-constant-span xs equ)
  (maximum 
    (map length
      (constant-spans xs equ))))

现在,maximum很容易

(define (maximum lon)
   (apply max lon))

我们剩下的任务是

(define (constant-spans xs equ)

for xs 可以是 empty

  (if (null? xs)
    (list (list))     ; [[]]

(返回 [[]] 因为 [1] => [[1]] 所以它应该是 [] => [[]]);或 non-empty,

    (let* ((a (car xs))
           (d (cdr xs))

并且由于我们正在对其进行编码,因此我们将在某个时候完成编写,然后我们就可以调用它,所以我们也可以call it,输入的一小部分,

           (r (constant-spans d equ))

然后我们将能够分析递归结果,我们知道永远不会为空——因为我们刚刚定义了空的处理方式上面的列表案例,返回 non-empty 列表 [[]] --

           (ra (car r))
           (rd (cdr r)))

(或者我们可以重复相同的 if ... null? ... let* ... car ... cdr ... 舞蹈...)(*)

所以现在,最后,我们决定如何处理这个递归结果,具体情况,其中的头元素 ra 是否为 empty ,

      (cond
        ((null? ra)   ; [[]] --> [[a]]
          (cons (cons a ra) rd))

或non-empty,所以我们可以窥视它,看看它的头元素是否相同 =31=],由 equ

认为
        ((equ a (car ra))  ; a [[a,...],...] --> [[a,a,...],...]
          (cons (cons a ra) rd))

不是 (这与我们在上面做的事情是一样的,呵呵。所以我们可以根据需要简化代码,稍后;但首先,):

        (else              ; a [[b,...],...] --> [[a],[b,...],...]
          (cons (list a) r))))))

就是这样。

如果我在这里犯了任何错误,请修正它们,使其正常工作。


(*) 哪个组合可以看作是一个基于原始 模式 的数据处理操作——有时称为 caseof -- 在 面向数据类型 范例下。 caseof 结合了数据案例检测、分析和变量绑定。

在这样的伪代码中,数据分析代码自然遵循数据类型定义:

type | [a, ..[b, c, ...]]
     | []
.......
rle xs equ =
  caseof xs
  | [] --> [[]]
  | [a, ..d] --> 
    caseof (rle d equ)
    | [] --> ...
    | [ra, ..rd] --> ...
........

使决策树在我们的代码中显而易见。