2017-06-23 6 views
-2

comment puis-je append (1 2 3) à la fin de () pour faire ((1 2 3))
Comment puis-je joins (4 5 6) à la fin de que pour faire ((1 2 3) (4 5 6))
comment puis-je ajouter "|" à la fin de que pour faire ((1 2 3) (4 5 6) "|")comment puis-je ajouter à une liste sans créer une paire en pointillés

sans paires en pointillés.

Je travaille avec Chicken Scheme mais je vais prendre une réponse de n'importe quel régime à ce stade. Notez que n'importe laquelle de ces listes pourrait aussi être une liste imbriquée de qui sait quoi ... Je suis en train d'écrire un exemple trivial.

note: @sjamaan montre une solution utilisant l'ajout qui consiste à tout emballer dans une autre liste pour compenser l'ajout de faire des choses AUTRES que ce que le nom dit.

(append (list 1 2 3) "|") ;=> (1 2 3 . "|") ;^^ didn't actually append, created a dotted pair (append '(1 2 3) (list 4 5 6)) ;=> (1 2 3 4 5 6) ; don't want unwrapped list ;^^ didn't actually append the list i gave it but appended the contents of the list.

Fondamentalement, je suis l'espoir d'une méthode append qui ajoute en fait ce que vous lui donnez, n'ajoute le contenu, ou il prend et fait une paire en pointillés. Peut-être que je suis juste un rêveur ... Je peux écrire une méthode "pas vraiment append" qui prend juste les params que vous lui donnez et les enveloppe dans une liste externe pour compenser mais c'est juste stupide ... Sûrement schéma a un moyen de append sans cette folie.

+0

double possible de [ce qui est le « contre » pour ajouter un élément à la fin de la liste ?] (https://stackoverflow.com/questions/6439972/what-is-the-cons-to-add-an-item-to-the-end-of-the-list) – jcolemang

+0

@jcolemang c'est similaire mais pas même. l'autre question est plutôt ambiguë et ne couvre pas le même motif.Il et ses réponses ne parviennent pas à répondre au fait que l'ajout d'une liste n'ajoute pas une liste mais le contenu, et n'adresse pas l'ajout d'un seul élément. – masukomi

Répondre

3

Voici comment append est fait:

(define (append2 lst1 lst2) 
    (if (null? lst1) 
     lst2        ; the second list is unaltered 
     (cons (car lst1) 
      (append2 (cdr lst1) lst2)))) 

fait une chaîne paire composée de tous les éléments lst1 et lst2.Il ne fait pas une paire où il y a nont en lst2 si:

(append2 '(1 2 3) '(4 5)) ; ==> (1 2 3 4 5) 
(append2 '(1 2 3) '()) ; ==> (1 2 3) and not (1 2 3()) 
(append2 '(1 2 3) '5)  ; ==> (1 2 3 . 5) 

Notez que chaque liste comme (1 2 3) est en fait (1 2 3 .()) ou encore plus correctement (1 . (2 . (3 .())))

Comment puis-je joins (1 2 3) à la fin de () pour faire ((1 2 3))

(define (insert-last e lst) 
    (let helper ((lst lst)) 
    (if (pair? lst) 
     (cons (car lst) 
       (helper (cdr lst))) 
     (cons e '())))) 

(insert-last '(1 2 3) '())      
; ==> ((1 2 3)) 

comment puis-je append (4 5 6) à la fin de que pour faire ((1 2 3) (4 5 6))

(insert-last '(4 5 6) '((1 2 3))) 
; ==> ((1 2 3) (4 5 6)) 

Comment puis-je joins "|" à la fin de que pour faire ((1 2 3) (4 5 6) "|")

(insert-last "|" '((1 2 3) (4 5 6))) 
; ==> ((1 2 3) (4 5 6) "|") 

Sachez que cela ressemble beaucoup à append. Ce sont la pire façon de faire cette liste puisque vous faites une nouvelle liste à chaque fois. C'est O (n) pour chaque insert et O (n^2) pour n éléments. Si vous pouvez le faire dans l'ordre inverse, vous obtenez quelque chose qui fait O (1) au lieu de O (n) pour chaque insertion. Au lieu de insert-last vous utilisez cons:

(cons '"|" '())    ; ==> ("|") 
(cons '(4 5 6) '("|"))  ; ==> ((4 5 6) "|") 
(cons '(1 2 3) '((4 5 6) "|") ; ==> ((1 2 3) (4 5 6) "|") 

Ceci est O (1), O (n) pour n éléments traités. Si vous avez besoin de le faire dans l'ordre d'origine, vous pouvez accumuler, puis inversez ..

(cons '(1 2 3) '())    ; ==> ((1 2 3)) 
(cons '(4 5 6) '((1 2 3)))   ; ==> ((4 5 6) (1 2 3)) 
(cons '"|" '((4 5 6) (1 2 3))) ; ==> ("|" (4 5 6) (1 2 3)) 
(reverse '("|" (4 5 6) (1 2 3)) ; ==> ((1 2 3) (4 5 6) "|") 

Ceci est O (1), puis O (n) pour l'inverse, mais il est encore O (1) amortis. O (n) pour n éléments que vous traitez.

+0

merci pour le temps et l'effort que cette réponse a pris. Je noterai que la réponse "| |" 'n'était pas juste, mais vous avez certainement répondu au coeur de la question. – masukomi

+0

@masukomi J'ai mis à jour la réponse pour corriger les '' | | '' s – Sylwester

+1

J'ai entendu 'insert-last' appelé' snoc' avant, incidemment. –

2

La procédure que vous cherchez est sans surprise appelée append (à partir de SRFI-1). Il ajoute une liste de choses sur une autre liste. Cela ne signifie pas que si vous voulez ajouter un seul élément, vous aurez besoin de faire une liste de ce:

(append '() '((1 2 3))) => ((1 2 3)) 
(append '((1 2 3)) '((4 5 6))) => ((1 2 3) (4 5 6)) 
(append '((1 2 3) (4 5 6)) '("|")) => ((1 2 3) (4 5 6) "|") 

Il accepte plusieurs arguments, qui seront tous être annexée à eachother dans cet ordre, vous peut également faire:

(append '() '((1 2 3)) '((4 5 6)) '("|")) => ((1 2 3) (4 5 6) "|") 

Espérons que cela aide!

+0

Je comprends ce que vous faites, mais ce n'est pas tout à fait la même chose. La différence est que, vous travaillez autour de la stupidité d'append en enveloppant tout dans une autre liste. Ajouter les éléments d'une liste à une autre serait quelque chose comme '(map (labmda (x) (ajouter une liste de destination (list x)).) J'espère que la solution ne sera pas" Hey, imbriquez tout dans une autre liste parce que append est stupide, puis faites-le. "Il n'y a pas de version plus directe? – masukomi

+0

La réponse est vraiment d'envelopper tout dans une liste.La raison en est que append ** déjà ** pour reconstruire la cellule de liste la structure de toutes les listes sauf la dernière (contenant l'atome) Pour les listes, il est logique de le faire de temps en temps, mais ajouter un atome à la fin est extrêmement inefficace, donc cela n'a pas de sens d'avoir Donc, si vous faites cela, regardez la suggestion de @ dan-d pour maintenir continuellement la liste inverse, contre le front et inversez-la une fois à la fin.C'est un modèle d'utilisation typique dans Scheme. – sjamaan

+0

Vous pouvez également conserver le dernier cdr de la liste et appeler 'se t-cdr! 'avec (encore) une liste contenant juste l'atome. Je recommande seulement de faire cela dans le code critique de performance, car il obscurcit votre algorithme et si la liste est passée dedans elle confond avec les données de l'appelant. Notez que c'est la manière habituelle de le faire avec des listes simples en C ou d'autres langages impératifs. – sjamaan

3

append n'ajoute pas d'atomes aux listes. Il concatène les listes. Vous devez lever l'atome jusqu'à une liste avant que la concaténation ait un sens.

(append xs (list y)) 

Mais il est logique de souligner (reverse (cons y (reverse xs))) qui a le même résultat. reverse suggère que vous pourriez construire votre liste en arrière si vous avez besoin d'ajouter des atomes à la fin.

0

Que vous le vouliez ou non, les cellules par contre seront créées, car les listes sont constituées de contre-cellules.

comment puis-je append (1 2 3) à la fin de() pour ((1 2 3))

CL-USER 24 > (list '(1 2 3)) 
((1 2 3)) 

comment je joins (4 5 6) à la fin de ce faire ((1 2 3) (4 5 6))

CL-USER 25 > (append '((1 2 3)) (list '(4 5 6))) 
((1 2 3) (4 5 6)) 

comment puis-je ajouter "|" à la fin de ce faire ((1 2 3) (4 5 6) « | »)

CL-USER 26 > (append '((1 2 3) (4 5 6)) (list "|")) 
((1 2 3) (4 5 6) "|")