-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMultiset.java
159 lines (121 loc) · 2.92 KB
/
Multiset.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
class Multiset<E> {
private List<E> values;
private List<Integer> frequency;
private final String ERROR_MSG = "Count cannot be negative: ";
public Multiset() {
values = new ArrayList<>();
frequency = new ArrayList<>();
}
public Multiset(Multiset<E> ms) {
values = new ArrayList<>();
frequency = new ArrayList<>();
ms.forEach((val)->{this.add(val);});
}
public int add(E element, int count) {
if (count < 0) {
throw new IllegalArgumentException(ERROR_MSG + count);
}
int index = values.indexOf(element);
int prevCount = 0;
if (index != -1) {
prevCount = frequency.get(index);
frequency.set(index, prevCount + count);
}
else if (count != 0) {
values.add(element);
frequency.add(count);
}
return prevCount;
}
public boolean add(E element) {
return add(element, 1) >= 0;
}
boolean addAll(Collection<? extends E> c){
for (E element: c)
add(element, 1);
return true;
}
public void addAll(E... arr) {
for (E element: arr)
add(element, 1);
}
public void forEach(Consumer<? super E> action)
{
List<E> all = new ArrayList<>();
for (int i = 0; i < values.size(); i++)
for (int j = 0; j < frequency.get(i); j++)
all.add(values.get(i));
all.forEach(action);
}
public boolean remove(Object element)
{
return remove(element, 1) > 0;
}
public int remove(Object element, int count)
{
if (count < 0) {
throw new IllegalArgumentException(ERROR_MSG + count);
}
int index = values.indexOf(element);
if (index == -1)
return 0;
int prevCount = frequency.get(index);
if (prevCount > count) {
frequency.set(index, prevCount - count);
}
else {
values.remove(index);
frequency.remove(index);
}
return prevCount;
}
public boolean contains(Object element) {
return values.contains(element);
}
public boolean containsAll(Collection<?> c) {
return values.containsAll(c);
}
public int setCount(E element, int count)
{
if (count < 0) {
throw new IllegalArgumentException(ERROR_MSG + count);
}
if (count == 0)
remove(element);
int index = values.indexOf(element);
if (index == -1)
return add(element, count);
int prevCount = frequency.get(index);
frequency.set(index, count);
return prevCount;
}
public int count(Object element) {
int index = values.indexOf(element);
return (index == -1) ? 0 : frequency.get(index);
}
public Set<E> elementSet() {
return values.stream().collect(Collectors.toSet());
}
public boolean isEmpty() {
return values.size() == 0;
}
public int size() {
int size = 0;
for (Integer i: frequency){
size += i;
}
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < values.size(); i++) {
sb.append(values.get(i));
if (frequency.get(i) > 1)
sb.append(" x ").append(frequency.get(i));
if (i != values.size() - 1)
sb.append(", ");
}
return sb.append("]").toString();
}
}