समथबेस्ट का टेर्स समाधान इसकी सादगी और लालित्य में बहुत संतोषजनक है, लेकिन मैं बड़ी संख्या में सेट के साथ काम कर रहा हूं और एक और अधिक प्रदर्शन करने वाला समाधान की आवश्यकता है जो अभी भी अपरिवर्तनीय है और अच्छी कार्यात्मक शैली में लिखी गई है।
प्रत्येक 10 तत्वों के साथ 10,000 सेट (यादृच्छिक रूप से 0 से 750,000 तक चुने गए इट्स) के लिए, सैमथेस्ट के टर्से समाधान ने मेरे कंप्यूटर पर औसत ~ 30sec लिया, जबकि मेरा समाधान औसत ~ 400ms पर लिया गया।
(मामले किसी को भी सोच रहा था में, ऊपर सेट cardinalities के लिए परिणामी सेट 3600 सेट, शामिल हैं ~ प्रत्येक ~ 26 तत्वों की औसत के साथ)
किसी को भी किसी भी सुधार देख सकते हैं अगर मैं शैली के संबंध में कर सकता है या प्रदर्शन, कृपया मुझे बताएं!
val sets = Set(Set(1, 2), Set(2, 3), Set(4, 5))
Association.associate(sets) => Set(Set(1, 2, 3), Set(4, 5))
object Association {
// Keep track of all current associations, as well as every element in any current association
case class AssociationAcc[A](associations: Set[Set[A]] = Set.empty[Set[A]], all: Set[A] = Set.empty[A]) {
def +(s: Set[A]) = AssociationAcc(associations + s, all | s)
}
// Add the newSet to the set associated with key A
// (or simply insert if there is no such key).
def updateMap[A](map: Map[A, Set[A]], key: A, newSet: Set[A]) = {
map + (key -> (map.getOrElse(key, Set.empty) ++ newSet))
}
// Turn a Set[Set[A]] into a map where each A points to a set of every other A
// it shared any set with.
//
// e.g. sets = Set(Set(1, 2), Set(2, 3), Set(4, 5))
// yields: Map(1 -> Set(2), 2 -> Set(1, 3), 3 -> Set(2),
// 4 -> Set(5), 5 -> Set(4))
def createAssociationMap[A](sets: Set[Set[A]]): Map[A, Set[A]] = {
sets.foldLeft(Map.empty[A, Set[A]]) { case (associations, as) =>
as.foldLeft(associations) { case (assoc, a) => updateMap(assoc, a, as - a) }
}
}
// Given a map where each A points to a set of every A it is associated with,
// and also given a key A starting point, return the total set of associated As.
//
// e.g. with map = Map(1 -> Set(2), 2 -> Set(1, 3), 3 -> Set(2),
// 4 -> Set(5), 5 -> Set(4))
// and key = 1 (or 2 or 3) yields: Set(1, 2, 3).
// with key = 4 (or 5) yields: Set(4, 5)
def getAssociations[A](map: Map[A, Set[A]], key: A, hit: Set[A] = Set.empty[A]): Set[A] = {
val newAssociations = map(key) &~ hit
newAssociations.foldLeft(newAssociations | hit + key) {
case (all, a) => getAssociations(map, a, all)
}
}
// Given a set of sets that may contain common elements, associate all sets that
// contain common elements (i.e. take union) and return the set of associated sets.
//
// e.g. Set(Set(1, 2), Set(2, 3), Set(4, 5)) yields: Set(Set(1, 2, 3), Set(4, 5))
def associate[A](sets: Set[Set[A]]): Set[Set[A]] = {
val associationMap = createAssociationMap(sets)
associationMap.keySet.foldLeft(AssociationAcc[A]()) {
case (acc, key) =>
if (acc.all.contains(key)) acc
else acc + getAssociations(associationMap, key)
}.associations
}
}
(_ कोष्ठक में फिल्टर में आप नहीं कर सकते) संकलन नहीं करता:
यहाँ मैं के साथ आया है। मैंने इसे ठीक करने के लिए संपादित किया और यह एक टेस्ट केस पर काम करता है जिसकी मैंने कोशिश की :) –
@ पॉल थक्स, और वास्तव में एक बग था जिसे मैंने अभी तय किया था। इसके अलावा मुझे लगता है - बहिष्कृत है, इसलिए इसे फ़िल्टर करने के लिए बदल दिया गया – samthebest
क्या आप 'विभाजन' को छेद के साथ सेट में 'cum' को विभाजित करने के लिए' विभाजन 'का उपयोग कर सकते हैं? थोड़ा स्पष्ट हो सकता है? –