Skip to content

Commit 65e4a7c

Browse files
authored
Adding a simple cascading solution to generate a Power Set (trekhleb#975)
* Add a simple cascading version of generating a PowerSet. * Update README. * Update README. * Update README.
1 parent a123b90 commit 65e4a7c

File tree

4 files changed

+115
-12
lines changed

4 files changed

+115
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ a set of rules that precisely define a sequence of operations.
9999
* **Sets**
100100
* `B` [Cartesian Product](src/algorithms/sets/cartesian-product) - product of multiple sets
101101
* `B` [Fisher–Yates Shuffle](src/algorithms/sets/fisher-yates) - random permutation of a finite sequence
102-
* `A` [Power Set](src/algorithms/sets/power-set) - all subsets of a set (bitwise and backtracking solutions)
102+
* `A` [Power Set](src/algorithms/sets/power-set) - all subsets of a set (bitwise, backtracking, and cascading solutions)
103103
* `A` [Permutations](src/algorithms/sets/permutations) (with and without repetitions)
104104
* `A` [Combinations](src/algorithms/sets/combinations) (with and without repetitions)
105105
* `A` [Longest Common Subsequence](src/algorithms/sets/longest-common-subsequence) (LCS)

src/algorithms/sets/power-set/README.md

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Power Set
22

33
Power set of a set `S` is the set of all of the subsets of `S`, including the
4-
empty set and `S` itself. Power set of set `S` is denoted as `P(S)`.
4+
empty set and `S` itself. Power set of set `S` is denoted as `P(S)`.
55

66
For example for `{x, y, z}`, the subsets
77
are:
@@ -21,37 +21,37 @@ are:
2121

2222
![Power Set](https://www.mathsisfun.com/sets/images/power-set.svg)
2323

24-
Here is how we may illustrate the elements of the power set of the set `{x, y, z}` ordered with respect to
24+
Here is how we may illustrate the elements of the power set of the set `{x, y, z}` ordered with respect to
2525
inclusion:
2626

2727
![](https://upload.wikimedia.org/wikipedia/commons/e/ea/Hasse_diagram_of_powerset_of_3.svg)
2828

2929
**Number of Subsets**
3030

31-
If `S` is a finite set with `|S| = n` elements, then the number of subsets
32-
of `S` is `|P(S)| = 2^n`. This fact, which is the motivation for the
31+
If `S` is a finite set with `|S| = n` elements, then the number of subsets
32+
of `S` is `|P(S)| = 2^n`. This fact, which is the motivation for the
3333
notation `2^S`, may be demonstrated simply as follows:
3434

35-
> First, order the elements of `S` in any manner. We write any subset of `S` in
36-
the format `{γ1, γ2, ..., γn}` where `γi , 1 ≤ i ≤ n`, can take the value
35+
> First, order the elements of `S` in any manner. We write any subset of `S` in
36+
the format `{γ1, γ2, ..., γn}` where `γi , 1 ≤ i ≤ n`, can take the value
3737
of `0` or `1`. If `γi = 1`, the `i`-th element of `S` is in the subset;
38-
otherwise, the `i`-th element is not in the subset. Clearly the number of
38+
otherwise, the `i`-th element is not in the subset. Clearly the number of
3939
distinct subsets that can be constructed this way is `2^n` as `γi ∈ {0, 1}`.
4040

4141
## Algorithms
4242

4343
### Bitwise Solution
4444

45-
Each number in binary representation in a range from `0` to `2^n` does exactly
46-
what we need: it shows by its bits (`0` or `1`) whether to include related
47-
element from the set or not. For example, for the set `{1, 2, 3}` the binary
45+
Each number in binary representation in a range from `0` to `2^n` does exactly
46+
what we need: it shows by its bits (`0` or `1`) whether to include related
47+
element from the set or not. For example, for the set `{1, 2, 3}` the binary
4848
number of `0b010` would mean that we need to include only `2` to the current set.
4949

5050
| | `abc` | Subset |
5151
| :---: | :---: | :-----------: |
5252
| `0` | `000` | `{}` |
5353
| `1` | `001` | `{c}` |
54-
| `2` | `010` | `{b}` |
54+
| `2` | `010` | `{b}` |
5555
| `3` | `011` | `{c, b}` |
5656
| `4` | `100` | `{a}` |
5757
| `5` | `101` | `{a, c}` |
@@ -68,6 +68,44 @@ element.
6868

6969
> See [btPowerSet.js](./btPowerSet.js) file for backtracking solution.
7070
71+
### Cascading Solution
72+
73+
This is, arguably, the simplest solution to generate a Power Set.
74+
75+
We start with an empty set:
76+
77+
```text
78+
powerSets = [[]]
79+
```
80+
81+
Now, let's say:
82+
83+
```text
84+
originalSet = [1, 2, 3]
85+
```
86+
87+
Let's add the 1st element from the originalSet to all existing sets:
88+
89+
```text
90+
[[]] ← 1 = [[], [1]]
91+
```
92+
93+
Adding the 2nd element to all existing sets:
94+
95+
```text
96+
[[], [1]] ← 2 = [[], [1], [2], [1, 2]]
97+
```
98+
99+
Adding the 3nd element to all existing sets:
100+
101+
```
102+
[[], [1], [2], [1, 2]] ← 3 = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
103+
```
104+
105+
And so on, for the rest of the elements from the `originalSet`. On every iteration the number of sets is doubled, so we'll get `2^n` sets.
106+
107+
> See [caPowerSet.js](./caPowerSet.js) file for cascading solution.
108+
71109
## References
72110

73111
* [Wikipedia](https://en.wikipedia.org/wiki/Power_set)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import caPowerSet from '../caPowerSet';
2+
3+
describe('caPowerSet', () => {
4+
it('should calculate power set of given set using cascading approach', () => {
5+
expect(caPowerSet([1])).toEqual([
6+
[],
7+
[1],
8+
]);
9+
10+
expect(caPowerSet([1, 2])).toEqual([
11+
[],
12+
[1],
13+
[2],
14+
[1, 2],
15+
]);
16+
17+
expect(caPowerSet([1, 2, 3])).toEqual([
18+
[],
19+
[1],
20+
[2],
21+
[1, 2],
22+
[3],
23+
[1, 3],
24+
[2, 3],
25+
[1, 2, 3],
26+
]);
27+
});
28+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Find power-set of a set using CASCADING approach.
3+
*
4+
* @param {*[]} originalSet
5+
* @return {*[][]}
6+
*/
7+
export default function caPowerSet(originalSet) {
8+
// Let's start with an empty set.
9+
const sets = [[]];
10+
11+
/*
12+
Now, let's say:
13+
originalSet = [1, 2, 3].
14+
15+
Let's add the first element from the originalSet to all existing sets:
16+
[[]] ← 1 = [[], [1]]
17+
18+
Adding the 2nd element to all existing sets:
19+
[[], [1]] ← 2 = [[], [1], [2], [1, 2]]
20+
21+
Adding the 3nd element to all existing sets:
22+
[[], [1], [2], [1, 2]] ← 3 = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
23+
24+
And so on for the rest of the elements from originalSet.
25+
On every iteration the number of sets is doubled, so we'll get 2^n sets.
26+
*/
27+
for (let numIdx = 0; numIdx < originalSet.length; numIdx += 1) {
28+
const existingSetsNum = sets.length;
29+
30+
for (let setIdx = 0; setIdx < existingSetsNum; setIdx += 1) {
31+
const set = [...sets[setIdx], originalSet[numIdx]];
32+
sets.push(set);
33+
}
34+
}
35+
36+
return sets;
37+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy