Функция Scheme для удаления первого элемента - PullRequest
0 голосов
/ 02 мая 2010

написать функцию схемы, которая удаляет вхождение первого верхнего уровня данного элемента из списка предметов. например, данный список (a b c), пункт b, список результатов (a c)

PLZ, помогите мне

Ответы [ 6 ]

3 голосов
/ 02 мая 2010

Подумайте, чего вы пытаетесь достичь.

У вас есть список вещей, и вы пытаетесь удалить определенный элемент.

 example: trying to remove b
 (a a a a b a a b a ...)
 anything before first b should be kept and anything after it also..
 so we have to spit out from our function:
 a a a a + a a b a ...

если бы мы сократили это до работы с рекурсией:

 at any point looking through the list you can:

 1. inspect element at front of the list and give it out to the result
    and recursively inspect the rest of the list
 2. stop if you found your element and 
    give out the rest of the list as you've accomplished your task
1 голос
/ 03 мая 2010

Не уверен, что вы хотите, но сначала запустите его просто с индексом, это примерно то, как вы должны «думать» со Схемой, сначала начните с «Что, если это был первый элемент?», Тогда ответ таков: конечно, это должно быть остальной частью списка. А затем «Ну, что, если это не первый», тогда ответ «Это должно состоять из первого до результата той же самой процедуры, примененной ко всем остальным.», Это все, что нужно Схеме информации в этом, и во многих случаях на самом деле.

    (define (slice-out lst k)
      (if (<= k 0) (cdr lst) ; if we want to remove the first (0) element, surely the result is simply the tail of the list?
          (cons (car lst) ; if it's higher than 0, we just cons the first element...
                (slice-out (cdr lst) (- k 1))))) ; to the result of the same method applied to the tail but with one lower k.

> (slice-out '(a b c d e) 2)
===>(a b d e)

Эта функция возвращает ошибку, если список слишком короткий для индекса.

Однако, если вы хотите вырезать по некоторому равенству с другим объектом, этого примера достаточно, теперь мы больше не вырезаем его из того, что достигли 0, но если он идентичен примеру поиска:

(define (slice-out-by-equality lst search)
  (if (equal? (car lst) search) (cdr lst)
      (cons (car lst)
            (slice-out-by-equality (cdr lst) search))))

> (slice-out-by-equality '(a b c d e) 'c)
===> (a b d e)

Используя те же принципы, этот возвращает ошибку, если элемент не найден .

Дело в том, что схема имеет много разновидностей сравнений на равенство, поэтому нам действительно нужно:

(define (make-slice-out comparison)
  (lambda (lst search)
    (let loop ((lst lst))
      (cond 
        ((null? lst) '())
        ((comparison (car lst) search) (cdr lst))
        (else (cons (car lst) (loop (cdr lst))))))))

Этот пример показывает, что такое Scheme, не уверен, что вы знакомы с ним, но мы использовали здесь замыкание, эта функция на самом деле принимает в качестве аргумента любую двоичную функцию сравнения, а затем вычисляет требуемую функцию, он также очищен, он больше не делает ошибку, если не найден, он возвращает, он просто возвращает старый список, потому что, если он достигает конца списка, но ничего еще не удалено, он просто возвращает его в () .

> ((make-slice-out =) '(1 2 3 6 3) 6)
===> (1 2 3 3); we just made an anonymous function here.

Но, вспомнив нашу первоначальную функцию, теперь мы можем определить ее просто так, предоставляя предикат «равно?» наша новая функция фактически оценивает нашу старую функцию (с важным активом, который теперь очищается):

(define slice-out-by-equality (make-slice-out equal?))

И, есть еще двоичное сравнение, как насчет этого более экзотического примера:

(define slice-out-less-than (make-slice-out <))

Мы создали функцию, которая вырезает первый элемент, который строго меньше, чем наш поисковый запрос, таким образом, это работает:

> (slice-out-less-than '(573 284 238 174 92 47) 100)
====> (573 284 238 174 47)

Хотя 47 также меньше 100, 92 является первым из тех, кто есть.

0 голосов
/ 03 мая 2010

(определить (удалить элемент списка в первую очередь накапливается) (cond
((ноль? Список) накапливать) (остальное (элемент cond ((= (список автомобилей))) (накапливать cons (список cdr)))(else (remove-first-occurence (список cdr)) (cons (список автомобилей) аккумулятор)))))))

(remove-first-occurence '(1 2 3) 2' ())

0 голосов
/ 02 мая 2010

Примерно так (если это домашнее задание):

(define (remove-first-occurence some-list find-symbol accum)
  (cond 
    [(empty? some-list) accum]
    [else (cond
           [(= (first some-list) find-symbol) (cons accum (rest some-list))]
           [else (remove-first-occurence (rest some-list) find-symbol (cons (first some-list) accum))]
           )]))

(remove-first-occurence '(1 2 3 4 3) 3 empty)
0 голосов
/ 02 мая 2010
perl2scheme -s \
'use strict; sub remove_first { \
grep { $_ ne $_[0] || $first++ } @{ $_[1] }; } \
print join(",",remove_first("b", ("a","b","c"));'

Тривиальная оставшаяся задача по реализации perl2scheme оставлена ​​в качестве упражнения для читателя.

0 голосов
/ 02 мая 2010

Есть те функции автомобиля и CDR, которые позволяют вам принимать участие в списке. Функция append позволяет объединять два списка в один. Я думаю, что они могут пригодиться. Также ознакомьтесь с функцией cons и убедитесь, что вы понимаете, что такое список на самом деле и как он связан с парами.

Например, вы можете действовать следующим образом. Возьмите свой список, вырежьте первый элемент и проверьте, что это. Если это тот, который нужно удалить, откажитесь от него. Если это не тот элемент, который нужно удалить, обработайте остальную часть списка, а затем добавьте этот элемент обратно в начале.

...