2013-06-26 4 views
1

Я пытаюсь написать код с использованием SCHEME, который принимает два аргумента, например '(2 1 3) &' (a b c) и дает список '(b a c). Мой код не работает ни рекурсивным, ни итеративным. Любая помощь!!Переупорядочить элементы в списке с помощью схемы

(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)))))) 
+0

Это улучшило бы читаемость кода, который вы опубликовали, если он был правильно отступом. Все основные среды разработки Схемы имеют функциональность, которая делает это автоматически. –

+0

Я скопировал отложенный код несколько раз, но все хуже. PS не удалось загрузить снимок. :/ – farey

+0

Gah есть промежутки здесь тоже D: D: – jozefg

ответ

1
(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))) 

Если вам нужен заказ, чтобы быть 'сложным' (как '(1 (2 3) 4)), а затем использовать это:

(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) 
> 

, а затем

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

любая идея о том, как решить для: order = '(2 (1 3) 4) & list =' (a b c d) - спасибо – farey

0

Первое, что пришло на ум:

(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 '())) 

Лучшее решение:

(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)) 
+0

OmG это работает. : D э. им просто новичок. :/ благодаря тонну. – farey

+0

@ user2523987 Первая функция слишком тяжелая, вторая должна быть лучше. –

+0

Вы понимаете, что 'nth-element' - это встроенная функция, называемая' list-ref', правильно? –

1

Вот версия, которая обрабатывает произвольно вложенных списков: во-первых, nested-map это как map но ручками вложенные списки:

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

Затем мы создаем картограф для использования с ним (с помощью list-ref если список короче, чем 16 элементов, в противном случае копирования в вектор первых для лучшей масштабируемости):

(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)) 

Обратите внимание, как, после того, как картограф является определенная, функция представляет собой просто один вызов nested-map. Легко! :-D

+0

Это не работает для примера OP ''(2 1 3) &' (a b c)'. –

+0

Теперь все в порядке ... –

+0

Большое спасибо. вы ppl потрясающие. Каков хороший способ обработки ошибок в схеме. я посмотрел дисплей & ~ r для сообщений, bt did not работает. – farey

0

Вот простой вариант для не- вложенные списки:

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

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

Если вам нужно использовать вложенные списки, распрямите пригождается:

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

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

Обратите внимание, что я использую индексы 0 на основе, как это принято на схеме.