Domanda

Ho una funzione che ottiene x(un valore) e xs(una lista) e rimuove tutti i valori maggiori di x dalla lista.Beh, non funziona, puoi dirmi perché?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
È stato utile?

Soluzione

Penso che sia questa la frase che non va bene:

(setf xst (remove elem xs))))

Il primo argomento a setf è il luogo, seguito dal valore.Sembra che tu lo abbia al contrario (e xst è uno dei due nil o non inizializzato).

Potrebbe essere più semplice farlo:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))

Altri suggerimenti

Per quanto ne so, il più conciso:

(defun bigger-elements (x xs) (remove x xs :test #'<))

restituendo un nuovo elenco, rimuove tutti gli elementi y da xs per i quali

(< y x)

oppure utilizzando il famoso LOOP:

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))

Ha funzionato così:

(defun filterBig (x xs)
  (remove-if (lambda (item) (> item x)) xs))

A cosa serviva il "#"?Non è stato compilato con esso.

Se vuoi farlo in Lisp Way, puoi usare la ricorsione per restituire il nuovo elenco:

(defun biggerElems (x xs)
  (cond ((null xs) NIL)
        ((< x (car xs))
         (biggerElems x (cdr xs)))
       (t
        (cons (car xs) (biggerElems x (cdr xs))))))

@Luís Oliveira

Questa soluzione è in contrasto con quella pubblicata nella domanda.Se avessimo bisogno di fare qualcosa di leggermente più complicato, è importante essere radicati nell'approccio ricorsivo alla manipolazione delle liste.

@Ben:Non è la chiamata setf ad essere sbagliata: il problema è che non sta aggiornando xs.

cioè:xst viene impostato su xs con l'elemento rimosso, ma xs non viene aggiornato.Se un secondo elemento deve essere rimosso, xst riporterà il primo al suo interno.

dovresti associare xst a xs e sostituire xs nella chiamata di rimozione con xst.Ciò rimuoverebbe quindi tutti gli elementi x è più grande di.cioè:

(defun biggerElems(x xs)
  (let ((xst xs))
    (dolist (elem xs)
      (when (> x elem)
        (setf xst (remove elem xst))))
    xst))

Potrebbe essere leggermente più veloce impostare xst su (copy-list xs) e quindi utilizzare delete invece di delete (delete è distruttivo...a seconda dell'implementazione, potrebbe essere più veloce di rimuovi.Poiché lo chiami più volte, potresti ottenere prestazioni migliori copiando l'elenco una volta ed eliminandolo in modo distruttivo).

In alternativa:

(defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own
  (loop for elem in xs when (<= x elem) collect elem))

Ripensando al tuo post originale, c'è un po' di confusione...dici di rimuovere tutti gli elementi più grandi di x, ma il tuo codice sembra che stia tentando di rimuovere tutti gli elementi x è più grande di.Le soluzioni che ho scritto restituiscono tutti gli elementi più grandi di x (cioè:rimuovi tutti gli elementi x è più grande di).

A cosa serviva il "#"?Non si è compilato con esso.

Errore di battitura.Normalmente ci si riferisce alle funzioni con #' (Piace (remove-if #'oddp list)), ma durante la modifica ho dimenticato di rimuovere il carattere "#".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top