list - 列表中最小元素的位置

标签 list scheme racket minimum

我想编写一个 Racket 函数,它接受一个列表并返回该列表中最小元素的位置。我已经编写了一个有效的函数:

  (define (min-position xs)
    (define (min-position2 count pos xs)
      (cond ((null? xs) #f)
            ((= 1 (length xs)) pos)
            ((< (car xs) (cadr xs))
             (min-position2 (+ count 1) pos (cons (car xs) (cddr xs))))
            (else (min-position2 0 (+ count pos 1) (cons (cadr xs) (cddr xs))))))
    (min-position2 0 0 xs))

示例输入和输出:

> (min-position '(9 8 7 6 5))
4
> (min-position '(9 8 1 6 5))
2
> (min-position '(0 1 2))
0

但是有没有更优雅的写法呢?

最佳答案

我不确定您所说的“优雅”是什么意思。例如,可能有一个 spiffier 算法。但这是我如何在保留您的基本方法的同时使代码更具可读性(恕我直言)。

一步一步:

您的输入/输出示例,重写为 check-equal? 测试:

#lang racket
(require rackunit)
(define (test f)
  (check-equal? (f '(9 8 7 6 5)) 4)
  (check-equal? (f '(9 8 1 6 5)) 2)
  (check-equal? (f '(0 1)) 0)
  (check-equal? (f '(0 1 2)) 0))

您的原始版本,但在 cond 子句中使用 [] 而不是 ()。

(define (min-position/v0 xs)
  (define (min-position2 count pos xs)
    (cond [(null? xs) #f]
          [(= 1 (length xs)) pos]
          [(< (car xs) (cadr xs))
           (min-position2 (+ count 1) pos (cons (car xs) (cddr xs)))]
          [else
           (min-position2 0 (+ count pos 1) (cons (cadr xs) (cddr xs)))]))
  (min-position2 0 0 xs))
(test min-position/v0)

使用 match 解构列表并使用 thisnext 之类的名称代替 (car xs)(cadr xs):

(define (min-position/match xs)
  (define (min-position2 count pos xs)
    (match xs
      [(list) #f]
      [(list _) pos]
      [(list this next more ...)
       (cond [(< this next)
              (min-position2 (+ count 1) pos (cons this more))]
             [else
              (min-position2 0 (+ count pos 1) (cons next more))])]))
  (min-position2 0 0 xs))
(test min-position/match)

将内部函数更改为 let loop ...。完全一样,只是更简洁了一点。

(define (min-position/match&loop xs)
  (let loop ([count 0] [pos 0] [xs xs])
    (match xs
      [(list) #f]
      [(list _) pos]
      [(list this next more ...)
       (cond [(< this next) (loop (+ count 1) pos (cons this more))]
             [else          (loop 0 (+ count pos 1) (cons next more))])])))
(test min-position/match&loop)

同样,这与您的原始算法相同。但我会发现快速理解更容易。

关于list - 列表中最小元素的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23133351/

相关文章:

lambda - 在一个函数中生成幂集,没有显式递归,并且只使用 Racket 中最简单的原语

scheme - 如何返回包含过程的评估参数的字符串?

scheme - LISP clause for and clause let ¿why?, making a programming language in racket using ragg

debugging - 如何使用Racket博士逐步调试一个Scheme程序?

python - 如何将字符串 append 到 float 列表

java - 假设列表类型是 int java

html - 在下拉列表 HTML 中有一个滚动条

python Pandas : list of integers as individual values of DataFrame

scheme - 更改 Racket 中的当前输入端口

scheme - 如果文件名已在列表中,则将其删除