0
votes

Dupliquer simple dans un vecteur

Compte tenu d'une liste d'entiers de 1 do 10 avec la taille de 5, comment vérifier s'il n'y a que 2 mêmes entiers dans la liste?

Par exemple P>

(check '(1 2 3 4 5))


6 commentaires

Qu'avez-vous essayé? Quoi spécifiquement avez-vous besoin d'aide?


@Carcigénier Je ne peux pas obtenir la logique derrière cela, je ne peux vraiment pas


Qu'en est-il du cas comme (vérifier '(1 1 2 2 3)) ?


Thats faux aswell, une seule paire est nécessaire


fréquences pourrait aider avec ce clojuredocs.org/clojure.core/frequencies


J'ai cité vos listes. Comme ils étaient, ils échouent des évaluations de la fonction.


6 Réponses :


4
votes

Voici une solution utilisant des fréquences pour compter des occurrences et filtrer pour compter le nombre de valeurs qui ne se produisent que deux fois: xxx pré>

qui donne: p>

user=> (->> '(2 2 4 5 7) frequencies)
{2 2, 4 1, 5 1, 7 1}
user=> (->> '(2 2 4 5 7) frequencies (filter #(= (second %) 2)))
([2 2])
user=> (->> '(2 2 4 5 7) frequencies (filter #(= (second %) 2)) count)
1


2 commentaires

Belle solution, qui fonctionne également avec d'autres types de collecte. IMHO, il serait bon de donner à la fonction un nom meilleur, moins générique, qui reflète également sa nature prédicative. Quelque chose comme contient-juste-une paire? ou ainsi.


Je suis d'accord avec ça.



0
votes

Vous pouvez faire quelque chose comme ça xxx


0 commentaires

1
votes
(check [xs] (->> xs distinct count (= 4)))

0 commentaires

3
votes

La réponse de Christian Gonzalez est élégante et géniale si vous êtes sûr que vous travaillez sur une petite contribution. Cependant, il est impatient: il oblige toute la liste des intrants même lorsque cela va en principe plus tôt que le résultat sera faux. Ceci est un problème si la liste est très importante ou si elle est une liste paresseuse dont les éléments sont coûteux à calculer - essayez-le sur (liste * 1 1 1 (gamme 1e9)) ! Je présente donc ci-dessous une alternative que les courts-circuits dès qu'il trouve un deuxième duplicata: xxx

naturellement, il est plutôt plus encombrant que l'approche sans soucis, mais je n'ai pas pu voir le moyen de Obtenez ce comportement à court-circuit sans tout faire à la main. J'aimerais voir une amélioration qui atteint le même résultat en combinant des fonctions de niveau supérieur.


4 commentaires

Si je ne me trompe pas, votre solution dupliquerait la collection (éventuellement énorme) dans le document défini sur le cas lorsque le résultat est true . Dans ce cas, vous échangeriez la vitesse de la mémoire. Ou ai-je tort?


@Stefankamphausen quel commerce? Chaque solution nécessite au moins autant d'espace que celui-ci. Comment trouverez-vous des doublons si vous ne vous souvenez pas de quels articles que vous avez vus jusqu'à présent? Celui-ci prend moins espace car il ne continue pas d'accumuler une carte une fois qu'elle sait qu'elle peut s'arrêter; Il ne stocke pas non plus un entier inutile pour chaque élément unique de l'entrée.


vous avez raison. J'ai oublié des fréquences dupliquer la collection aussi.


J'ai essayé une solution combinatoire .



1
votes

En réponse au plaidoyer d'Alan Malloy, voici une solution quelque peu combinatoire: xxx pré>

ceci p>

  • crée une séquence paresseuse de l'ensemble accumulant; Li>
  • le teste contre chaque nouvel élément correspondant; li>
  • Filtres pour le TRUE code> Cases - Ceux où l'élément est déjà présent; li>
  • teste s'il y en a exactement l'un d'entre eux. LI> ul>

    C'est paresseux, mais duplique les activités de numérisation de la collection donnée. Je l'ai essayé sur l'exemple de Alan Malloy: P>

    => (check (list* 1 1 1 (range 1e20)))
    false
    


7 commentaires

Ah, très bon. Une légère erreur: vous devez utiliser SEQ et suivant au lieu de d'abord et second , sinon vous risquez de vous tromper Réponse sur une collection contenant des booléens ou nulle. EDIT: Non, je vois - Vous vérifiez une liste connue pour contenir uniquement true s. Dans ce cas, vous pouvez remplacer le tout-pred entièrement avec (= [true]) , n'est-ce pas?


@Amalloy a essayé (= [true]) . Il perd la paresse. C'est un bug, sûrement. (= (liste true)) fonctionne.


C'est un résultat très intéressant. J'ai été surpris de constater que (= (plage) []) renvoie false immédiatement, mais (= [] (plage)) des boucles indéfiniment. Apparemment, cela a été le cas ~ pour toujours et je n'ai jamais remarqué.


@Amalloy Si la première collection est comptée, essaye-t-elle de compter la seconde, qu'elle soit comptée ou non? Ceci est évitable. Votre billet ou le mien?


C'est compliqué. Le problème est dans C.L.APERSISTENVector / Doequiv, qui suppose que des instances de J.U.List ont une méthode de taille rapide (), même si chaque collection de clojure est une liste mais toutes les toutes sont comptées.


@Amalloy si la question va au groupe Google? le groupe Google Dev? Un opérateur asymétrique = entraînant une défaillance inutile de se terminer, semble un prix élevé à payer pour une prestation de performance douteuse. Je suppose que le compté Ness pourrait être vérifié.


Si c'était moi, je voudrais simplement déposer un billet Jira. Mais je ne participe plus à Clojure Dev plus. Si vous pensez que vous pourriez obtenir des conseils utiles de Clojure-Dev, alors cela ressemble à une meilleure approche.



0
votes

Semblable aux autres utilise des fréquences - Appliquer deux fois sur

(def coll '(2 1 4 4 4))

frequencies=> {2 1, 1 1, 4 3}
vals=> (1 1 3)
frequencies=> {1 2, 3 1}
(get (frequencies #) 2)=> nil


0 commentaires