简体   繁体   中英

rearrange elements in a List using Scheme

I am trying to write a code using SCHEME that takes two arguments, for example '(2 1 3) & '(abc) and gives a list '(bac). My code is not working either recursive or iterative. Any help!!

(define project 
(lambda (list1 list2 list3 n b index)
(define n (length(list1)))
   (let ((i n))
     (for-each (i)
        (cond 
            ((null? list1) (display "empty"))
            (else
                (define n (car list1))
                (define index (- n 1)) 
                (define b (list-ref list2 index)) 
                (define list3 (cons list3 b)) 
                (define list1 (cdr list1)) 
                list3 ))))))

Here's a version that handles arbitrarily-nested lists: first, a nested-map that is like map but handles nested lists:

(define (nested-map func tree)
  (if (list? tree)
      (map (lambda (x)
             (nested-map func x))
           tree)
      (func tree)))

Then, we create a mapper to use with it (using list-ref if the list is shorter than 16 elements, otherwise copying to a vector first for better scalability):

(define (rearrange indices lst)
  (define mapper (if (< (length lst) 16)
                     (lambda (i)
                       (list-ref lst (- i 1)))
                     (let ((vec (list->vector lst)))
                       (lambda (i)
                         (vector-ref vec (- i 1))))))
  (nested-map mapper indices))

Notice how, after the mapper is defined, the function is simply a single call to nested-map . Easy! :-D

(define (rearrange order l)
  (cond ((number? order) (rearrange (list order) l))
        ((list?   order) (map (lambda (num) (list-ref l (- num 1))) order))
        (else 'bad-order)))

If you need order to be 'complex' (like '(1 (2 3) 4) ) then use this:

(define (listify thing)
  (cond ((null? thing) '())
        ((pair? thing) (apply append (map listify thing)))
        (else (list thing))))

> (listify 10)
(10)
> (listify '(1 (2 3) 4))
(1 2 3 4)
> 

and then

(define (rearrange order l)
  (map (lambda (num) (list-ref l (- num 1)))
       (listify order)))

First that came to mind:

(define (rearrange order symbols)
  (define (element i list)
    (if (= i 1) 
      (car list)
      (element (- i 1) (cdr list))))
  (define (iter order output)
    (if (null? order) 
      output
      (iter (cdr order) 
            (append output (list (element (car order) symbols))))))
  (iter order '()))

Better solution:

(define (rearrange order symbols)
  (define (nth-element i list)
    (if (= i 1)
      (car list)
      (nth-element (- i 1) (cdr list))))
  (map (lambda (x) (nth-element x symbols)) order))

Here's a simple version for un-nested lists:

(define (arrange idx lst)
  (map (lambda (i) (list-ref lst i)) idx))

(arrange '(1 0 2) '(a b c))
=> '(b a c)

If you need to use nested lists, flatten comes in handy:

(define (arrange idx lst)
  (map (lambda (i) (list-ref lst i)) (flatten idx)))

(arrange '(1 (0 2)) '(a b c))
=> '(b a c)

Note that I use 0-based indexes, as is the custom in Scheme.

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