简体   繁体   中英

Racket exchanging first and third elements of a list in a function?

Suppose, I got a list(s) in Racket of:

`(1 2 3)

`(1 2 3 4)

`((1 2) (3) (4)))

Then when I exchange it (first and third element), it will look like:

`(3 2 1)

`(3 2 1 4)

`((4) (3) (1 2))

Please note: I may only use things such as cons, first, and rest for this.

Here's my current try:

(define new-list
(lambda(list)
  (first (rest (rest list))))) ; Get third element.

I cannot replicate the results above. I would like to be shown how it's done.

Just play with it a little:

> '(one)
'(one)
> '(one two three)
'(one two three)
> (first '(one two three four))
'one
> (rest '(one two three four))
'(two three four)
> (define foo (lambda (lst)
    (cons (first lst) (rest lst))))
> (foo '(one two three four))
'(one two three four)
> (define bar (lambda (lst)
    (cons (first (rest lst))
          (cons (first lst) (rest lst)))))
> (bar '(one two three four))
'(two one two three four)

Now you have everything to complete the process.

To write your procedure, we want to take an input list xs , and construct a new list like

(cons (third-element xs)
      (cons (second-element xs)
            (cons (first-element xs)
                  (everything-except-the-first-three-elements xs)))

In racket you have car and cdr , but you also have cadr , caddr , cddddr and everything in betweeen .

To get an intuition for them, a reads the head, d reads the tail, so

  • car gets the head (the first element in a list)
  • cdr gets the tail (everything except the first element in a list)
  • cadr gets the head of the tail (the second element in a list)
  • cddr gets the tail of the tail (everything except the first and second elements in a list)
  • caddr gets the head of the tail of the tail (the third element in a list)
  • and so on ...

We can write this easily using our car and cdr helpers

(define (swap xs)
  (cons (caddr xs)                  ; cons the third element ...
        (cons (cadr xs)             ; onto the second element ...
              (cons (car xs)        ; onto the first element ...
                    (cdddr xs)))))  ; onto the tail of the third element

(swap '(1 2 3))         ; '(3 2 1)
(swap '(1 2 3 4))       ; '(3 2 1 4)
(swap '((1 2) (3) (4))) ; '((4) (3) (1 2))
(define nth 
  ;; Return nth element of list
  (lambda (lst n)
    (cond ((null? lst) 'nil)
          ((zero? n)   (car lst))
          (else (nth (cdr lst) (- n 1))))))

(define slice
  ;; Return lst sliced like python
  (lambda (lst a b acc)
    (cond ((null? lst) (reverse acc))
          ((< b a) (reverse acc))
          ((zero? b) (reverse acc))
          ((zero? a) (slice (cdr lst) 0 (- b 1) (cons (car lst) acc)))
          (else (slice (cdr lst) (- a 1) (- b 1) acc)))))

(define swap
  ;; Return nth and mth element swapped list
  (lambda (lst n m)
    `(,@(slice lst 0 n '()) 
      ,(nth lst m)
      ,@(slice lst (+ n 1)  m '())
      ,(nth lst n)
      ,@(slice lst (+ m 1) (length lst) '()))))

This swaps any two given positions m and n and returns the resulting list.

(swap your-list 0 2) ; returns your-list 1st and 3rd elements swapped

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM