10

如何在Scheme中创建一个连续数字列表?

在 Python 中创建从 1 到 10 的整数列表将是range(1,11). 是否有方案的等价物?

mzscheme --versionWelcome to Racket v5.2.1.

编辑:根据https://stackoverflow.com/a/7144310/596361实现范围功能,需要此代码:

#lang racket
(require srfi/1)
(iota 5 1)
4

7 回答 7

12

寻找iota(在 SRFI-1 中定义)。

示例: (iota 10 1) 给出从 1 开始的 10 个连续整数(而不是默认的 0)。

iota不采用与 range 相同的参数,但它复制了所有功能 - 升序范围,降序范围,如果只给出一个边界,则从 0 开始,指定间隔的能力。

于 2012-10-16T08:16:03.700 回答
5

这是一个版本,如果第一个数字较低,则执行升序范围;如果第一个数字较高,则执行降序范围:

(define range
  (lambda (n m)
    (cond
      ((= n m) (list n))
        (else (cons n (range ((if (< n m) + -) n 1) m))))))

这是一个改进的版本,可以接受 1 或 2 个参数;如果只给出一个,它的范围是从 0 到给定的数字:

(define range
  (lambda (n . m)
    (let
      ((n (if (null? m) 0 n)) (m (if (null? m) n (car m))))
      (cond
    ((= n m) (list n))
    (else (cons n (range ((if (< n m) + -) n 1) m)))))))
于 2012-10-16T09:16:17.560 回答
5

Racket 中有一个内置的range函数,其行为类似于 Python。

> (range 10)
'(0 1 2 3 4 5 6 7 8 9)
于 2014-05-24T07:17:30.793 回答
3

如果没有内置任何内容,那么编写自己的内容很简单:

(define (range first last)
  (if (>= first last)
      '()
      (cons first (range (+ first 1) last))))

在线方案评估器:http ://eval.ironscheme.net/?id=71

于 2012-10-16T08:28:32.087 回答
1

我只是将@Ankur 的评论提升为答案。在球拍中,您有“范围内”:

#lang racket

(in-range 7)  ;; produces #<stream>

;; used in a loop:
(for/list ([i (in-range 7)])
  i)
;; produces (list 0 1 2 3 4 5 6)


;; and, for the lazy among us:

(for/list ([i 7])
  i)

;; produces the same

它还可以接受下限、增量(包括负数)等。

于 2012-10-16T16:51:51.100 回答
0

根据 Germán Diago 的评论,我为此制作了一个纯功能惰性版本(即流)。它可以构造一个任意大小的范围流,您的 Scheme 实现可以在恒定时间内处理,以及访问当前元素并推进流,也在恒定时间内。

(define ^range
    (lambda (x y getter)
      (op x y getter)))

(define EOS ; End of stream for finite streams
    (^range '() '() (lambda () EOS)))

(define range 
    (lambda (x . y) ; if y < x then stream is infinite
      (let ((x (if (null? y) 0 x))
            (y (if (null? y) x (car y))))
        (^range x y (lambda ()
                      (if (= x y) EOS 
                       (range (+ x 1) y)))))))

(define get ; Get current element
    (lambda (r)
      (r (lambda (x y g) x))))

(define next ; Get stream for next element
    (lambda (r)
      (r (lambda (x y g) (g)))))

使用此代码:

> (define r (range 1 3))
> (get r)
1
> (get (next r))
2
> (get (next (next r)))
3
> (get (next (next (next r)))) ; EOS
()
于 2018-10-09T09:17:45.447 回答
-1

没有找到我想要的并且不想使用外部包,我最终编写了自己的版本,该版本不同于 python 版本(希望对其进行改进)。如果您认为它确实效率低下并且可以改进它,请这样做。

;; A version of range taking the form (range [[first] last [[step]]] ).
;; It takes negative numbers and corrects STEP to the same direction
;; as FIRST to LAST then returns a list starting from FIRST and
;; ending before LAST
(define (range . args)
  (case (length args)
   ( (0) '())
   ( (1) (range 0 (car args) (if (negative? (car args)) -1 1)))
   ( (2) (range (car args) (cadr args)
             (if (>= (car args) (cadr args)) -1 1)))
   ( (3) (let* ((start (car args)) (end (cadr args)) 
                (step (if (> start end)
                          (- (abs (caddr args))) 
                          (abs (caddr args)))))
            (let loop ((x start) (xs '()))
               (cond ((and (>= end start) (<= end x))
                      (reverse xs))
                     ((and (<= end start) (>= end x))
                      (reverse xs))
                     (else (loop (+ x step) (cons x xs)))))))
   (else (error 'range "too many arguments"))))
;  (else (display "ERROR: range too many arguments") (newline)))) ;;r4rs

;; (range-inc [[first] last [[step]]] ) includes LAST in the returned range
(define (range-inc . args)
  (case (length args)
    ( (0) '())
    ( (1) (append (range (car args)) args))
    ( (2) (append (range (car args) (cadr args)) (cdr args)))
    ( (3) (append (range (car args) (cadr args) (caddr args))
                  (list (cadr args))))
    (else (error 'range "too many  arguments"))))
;   (else (display "ERROR: range too many arguments") (newline)))) ;;r4rs

注意我也写了一个通用的 lisp版本

于 2018-07-17T08:22:46.000 回答