source: utilitiespy/tudelft/utilities/immutablelist/SubList.py@ 958

Last change on this file since 958 was 309, checked in by wouter, 3 years ago

#103 added PowerSet and SubList

File size: 2.3 KB
Line 
1from typing import TypeVar
2
3from tudelft.utilities.immutablelist.AbstractImmutableList import AbstractImmutableList
4from tudelft.utilities.immutablelist.ImmutableList import ImmutableList
5
6
7def bitCount(n:int):
8 '''
9 @return number of 1's in binary representation of number
10 '''
11 count = 0
12 while (n):
13 count += n & 1
14 n >>= 1
15 return count
16
17
18T=TypeVar("T")
19class SubList(AbstractImmutableList[T]):
20 '''
21 Selects a specific sublist of the given list.
22 This is a sort of subset, but the original order of the elements is
23 maintained. Notice this is not a cheap operation.
24
25 @param T the element type of all lists that we receive.
26 '''
27
28 def __init__(self, lis: ImmutableList[T], selection:int):
29 '''
30 @param lis the list to take the subset of. The list size must be
31 ≤ {@link Integer#MAX_VALUE} elements
32 @param selection a number. When interpreted binary, eg 1011, the 1's
33 indicate selected elements and 0's non-selected
34 elements. This number should be in the range
35 0..2^(|list|+1).
36 '''
37 self._list = lis
38 self._selection = selection
39
40 def get(self, index:int) -> T:
41 return self._list.get(self._getIndex(index))
42
43
44 def _getIndex(self, n1:int)->int:
45 '''
46 @param n the index in our list. We use int as int's are used anyway
47 internally in BigInteger for indexing bits.
48 @return the index in the original array, which is the index of the nth 1
49 in the selection number. NOTICE this is expensive operation as we
50 have to iterate to get to the required element.
51 '''
52 n = n1
53 for i in range(self._selection.bit_length()):
54 if self._selection >>i & 1:
55 if n == 0:
56 return i
57 n-=1
58 raise IndexError("Index out of bounds:" + str(n1))
59
60 def size(self) -> int:
61 return bitCount(self._selection)
62
63 def getSelection(self) -> int:
64 return self._selection
65
66 def complement(self)-> "SubList[T]" :
67 '''
68 @return list with all elements from list that were not selected now
69 selected, and those that were selected now not selected.
70 '''
71 # do 111111 XOR the selection.
72 sel = (1<<self._list.size()) - 1
73 sel = sel ^ self._selection
74 return SubList[T](self._list,sel)
75
76 def __hash__(self):
77 return hash((self._list, self._selection))
78
79 def __eq__(self, other):
80 return isinstance(other, self.__class__) \
81 and self._list==other._list\
82 and self._selection==other._selection
Note: See TracBrowser for help on using the repository browser.