Je recherche une belle façon d'aplatir (fractionner) une liste de plages numériques potentiellement chevauchantes. Le problème est très similaire à celui de cette question: moyen le plus rapide de fractionner les plages de dates qui se chevauchent , et bien d'autres.
Cependant, les plages ne sont pas uniquement des entiers, et je recherche un algorithme décent qui peut être facilement implémenté en Javascript ou Python, etc.
Exemples de données:
Exemple de solution:
Toutes mes excuses s'il s'agit d'un doublon, mais je n'ai pas encore trouvé de solution.
javascript
algorithms
python
Jollywatt
la source
la source
Réponses:
Marchez de gauche à droite en utilisant une pile pour garder une trace de la couleur sur laquelle vous vous trouvez. Au lieu d'une carte discrète, utilisez les 10 nombres de votre jeu de données comme points d'arrêt.
En commençant avec une pile vide et en mettant
start
à 0, bouclez jusqu'à ce que nous atteignions la fin:start
, et poussez-la et toutes les couleurs de rang inférieur sur la pile. Dans votre liste aplatie, marquez le début de cette couleur.start
, et trouvez la fin de la couleur actuellestart
à la fin de cette couleur, retirez-la de la pile et vérifiez la couleur classée la plus élevée suivante.start
trouve dans la plage de couleurs suivante, ajoutez cette couleur à la liste aplatie, en commençant parstart
.Ceci est un passage mental étant donné vos données d'exemple:
la source
Cette solution semble la plus simple. (Ou du moins, le plus facile à saisir)
Il suffit d'une fonction pour soustraire deux plages. En d'autres termes, quelque chose qui donnera ceci:
Ce qui est assez simple. Ensuite, vous pouvez simplement parcourir chacune des plages, en commençant par la plus basse, et pour chacune, en soustraire à tour de rôle toutes les plages au-dessus. Et voila.
Voici une implémentation du soustracteur de plage en Python:
En utilisant cette fonction, le reste peut être fait comme ceci: (Un 'span' signifie une plage, car 'range' est un mot-clé Python)
Cela donne
[['red', [12.5, 13.8]], ['blue', [0.0, 2.0]], ['green', [2.0, 3.5]], ['green', [10.0, 12.0]], ['yellow', [3.5, 6.7]], ['orange', [6.7, 10.0]]]
, ce qui est correct.la source
Si la portée des données est similaire à celle de vos exemples de données, vous pouvez créer une carte comme celle-ci:
Parcourez ensuite cette carte pour générer les plages
Pour fonctionner, les valeurs doivent être dans une plage relativement petite, comme dans vos exemples de données.
Modifier: pour travailler avec de vrais flottants, utilisez la carte pour générer une cartographie de haut niveau, puis référez-vous aux données d'origine pour créer les limites.
la source
Voici une solution relativement simple dans Scala. Il ne devrait pas être trop difficile de porter dans une autre langue.
apply
prend dans uneSet
de toutes les plages qui ont déjà été appliquées, trouve les chevauchements, puis retourne un nouvel ensemble moins les chevauchements et plus la nouvelle plage et les plages nouvellement divisées.foldLeft
appels répétésapply
avec chaque plage d'entrée.la source
Gardez simplement un ensemble de plages triées par début. Ajoutez une gamme qui couvre tout (-oo .. + oo). Pour ajouter une plage r:
la source