diff --git a/src/Containers-OrderedSet-Tests/CTOrderedSetTest.class.st b/src/Containers-OrderedSet-Tests/CTOrderedSetTest.class.st index acea903..c4fac05 100644 --- a/src/Containers-OrderedSet-Tests/CTOrderedSetTest.class.st +++ b/src/Containers-OrderedSet-Tests/CTOrderedSetTest.class.st @@ -163,21 +163,31 @@ CTOrderedSetTest >> testAllLargestSubsets [ self assert: actual equals: expected. ] +{ #category : #'performance tests' } +CTOrderedSetTest >> testAllSubsetsPerformance [ + | set time | + set := CTOrderedSet withAll: (1 to: 10) asArray. "Set of size 10" + + time := [ set allSubsets ] timeToRun. + self assert: set allSubsets size equals: (1 bitShift: 10) - 2. "1022 subsets" + self assert: time < 1 second description: 'Should complete within 1 second for size 10'. +] + { #category : #tests } CTOrderedSetTest >> testAllSubsets [ | set expected actual | set := CTOrderedSet withAll: #(a c b). - + expected := { CTOrderedSet withAll: #(a) . CTOrderedSet withAll: #(c) . - CTOrderedSet withAll: #(b) . - CTOrderedSet withAll: #(a c) . + CTOrderedSet withAll: #(a c) . + CTOrderedSet withAll: #(b) . CTOrderedSet withAll: #(a b) . CTOrderedSet withAll: #(c b) }. - + actual := set allSubsets. - self assert: actual equals: expected. + self assert: actual equals: expected. ] { #category : #'ordered collection tests' } diff --git a/src/Containers-OrderedSet/CTOrderedSet.class.st b/src/Containers-OrderedSet/CTOrderedSet.class.st index 1a1c878..a646559 100644 --- a/src/Containers-OrderedSet/CTOrderedSet.class.st +++ b/src/Containers-OrderedSet/CTOrderedSet.class.st @@ -37,13 +37,22 @@ CTOrderedSet >> allLargestSubsets [ { #category : #'as yet unclassified' } CTOrderedSet >> allSubsets [ - "Generate all possible subsets of this self without self and an empty set. - Example: - {1, 2, 3} => {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}" + "Generate all possible subsets of the receiver, excluding the receiver itself and the empty set. + Uses a bitmask approach for efficiency. + Example: #(a b c) => #(a), #(b), #(c), #(a b), #(a c), #(b c)" + + | subsets size | + size := self size. + subsets := OrderedCollection new: (1 bitShift: size) - 2. "Reserve space for 2^n - 2 subsets" + + 1 to: (1 bitShift: size) - 2 do: [ :mask | + | subset | + subset := self species new. + 1 to: size do: [ :index | + (mask bitAt: index) = 1 ifTrue: [ subset addLast: (self at: index) ] ]. + subsets add: subset ]. - "This implementation might not be very fast and has to be improved" - ^ (self combinations copyWithout: self asArray) collect: [ :eachArray | - self species withAll: eachArray ] + ^ subsets asArray ] { #category : #accessing }