1 28 29 package com.caucho.util; 30 31 public class IntSet { 32 int []data; 33 int size; 34 35 public void clear() { 36 size = 0; 37 } 38 39 private void expand(int max) { 40 while (max > data.length) { 41 int []next = new int[data.length * 2]; 42 43 for (int i = 0; i < data.length; i++) 44 next[i] = data[i]; 45 46 data = next; 47 } 48 } 49 50 public int length() { return size / 2; } 51 public int size() { return size / 2; } 52 53 public int getMin(int i) { return data[2 * i]; } 54 public int getMax(int i) { return data[2 * i + 1]; } 55 56 private void insert(int i, int min, int max) { 57 expand(size + 2); 58 59 System.arraycopy(data, i, data, i + 2, size - i); 60 61 data[i] = min; 62 data[i + 1] = max; 63 64 size += 2; 65 } 66 67 private void delete(int i) { 68 System.arraycopy(data, i + 2, data, i, size - i - 2); 69 70 size -= 2; 71 } 72 73 76 public void union(int min, int max) { 77 for (int i = 1; i < size; i += 2) { 78 if (max < data[i - 1] - 1) { 79 insert(i - 1, min, max); 80 return; 81 } 82 83 if (min > data[i] + 1) 84 continue; 85 86 if (min < data[i - 1]) 87 data[i - 1] = min; 88 if (max > data[i]) 89 data[i] = max; 90 91 int j = i + 2; 92 while (j < size && max > data[j - 1] + 1) { 93 if (max < data[j - 1]) 94 data[i] = data[j - 1]; 95 96 delete(j - 1); 97 } 98 return; 99 } 100 101 insert(size, min, max); 102 } 103 104 107 public void union(int value) { 108 union(value, value); 109 } 110 111 114 public void union(IntSet set) { 115 for (int i = 1; i < set.size; i += 2) 116 union(set.data[i - 1], set.data[i]); 117 } 118 119 122 public void unionNegate(IntSet set, int min, int max) { 123 for (int i = 1; i < set.size; i += 2) { 124 union(min, set.data[i - 1] - 1); 125 min = set.data[i] + 1; 126 } 127 union(min, max); 128 } 129 130 133 public void negate(int minValue, int maxValue) { 134 int max = minValue; 135 136 if (size > 0 && data[0] == minValue) { 137 max = data[1]; 138 delete(0); 139 if (max == maxValue) 140 return; 141 else 142 max++; 143 } 144 145 for (int i = 1; i < size; i += 2) { 146 int newMax = data[i]; 147 data[i] = data[i - 1] - 1; 148 data[i - 1] = max; 149 150 if (newMax == maxValue) 151 return; 152 max = newMax + 1; 153 } 154 155 insert(size, max, maxValue); 156 } 157 158 161 public void negate() { 162 negate(Integer.MIN_VALUE, Integer.MAX_VALUE); 163 } 164 165 170 public boolean difference(IntSet set) 171 { 172 int i = 1; 173 int j = 1; 174 175 while (i < size && j < set.size) { 176 int aMin = data[i - 1]; 177 int aMax = data[i]; 178 179 int bMin = set.data[j - 1]; 180 int bMax = set.data[j]; 181 182 if (bMax < aMin) { 185 j += 2; 186 } 187 else if (aMax < bMin) { 190 i += 2; 191 } 192 else if (bMin <= aMin && aMax <= bMax) { 195 delete(i - 1); 196 } 197 else if (aMin < bMin && bMax < aMax) { 200 insert(i + 1, bMax + 1, aMax); 201 data[i] = bMin - 1; 202 i += 2; 203 j += 2; 204 } 205 else if (aMin < bMin) { 208 data[i] = bMin - 1; 209 i += 2; 210 } 211 else if (aMax > bMax) { 214 data[i - 1] = bMax + 1; 215 j += 2; 216 } 217 else { 218 throw new RuntimeException ("Impossible case"); 219 } 220 } 221 222 return size != 0; 223 } 224 225 230 public boolean intersection(IntSet set) 231 { 232 int i = 1; 233 int j = 1; 234 235 while (i < size && j < set.size) { 236 int aMin = data[i - 1]; 237 int aMax = data[i]; 238 239 int bMin = set.data[j - 1]; 240 int bMax = set.data[j]; 241 242 if (bMax < aMin) { 245 j += 2; 246 } 247 else if (aMax < bMin) { 250 delete(i - 1); 251 } 252 else if (bMin <= aMin && aMax <= bMax) { 255 i += 2; 256 } 257 else if (aMin <= bMin && bMax <= aMax) { 260 data[i - 1] = bMin; 261 data[i] = bMax; 262 if (bMax < aMax) 263 insert(i + 1, bMax + 1, aMax); 264 i += 2; 265 j += 2; 266 } 267 else if (aMin <= bMin) { 270 data[i - 1] = bMin; 271 i += 2; 272 } 273 else if (bMin < aMin) { 276 data[i] = bMax; 277 insert(i + 1, bMax + 1, aMax); 278 i += 2; 279 } 280 else { 281 throw new RuntimeException ("case"); 282 } 283 } 284 285 while (i < size) 286 delete(i - 1); 287 288 return size != 0; 289 } 290 291 294 public boolean contains(int test) 295 { 296 for (int i = 1; i < size; i += 2) { 297 if (test < data[i - 1]) 298 return false; 299 if (test <= data[i]) 300 return true; 301 } 302 303 return false; 304 } 305 306 309 public boolean isSubset(IntSet subset) 310 { 311 int i = 1; 312 int j = 1; 313 314 while (i < size && j < subset.size) { 315 if (data[i] < subset.data[j - 1]) 316 i += 2; 317 else if (subset.data[j - 1] < data[i - 1] || subset.data[j] > data[i]) 318 return false; 319 else 320 j += 2; 321 } 322 323 return true; 324 } 325 326 329 public boolean isDisjoint(IntSet set) 330 { 331 int i = 1; 332 int j = 1; 333 334 while (i < size && j < set.size) { 335 if (data[i] < set.data[j - 1]) 336 i += 2; 337 else if (set.data[j] < data[i - 1]) 338 j += 2; 339 else 340 return false; 341 } 342 343 return true; 344 } 345 346 349 public String toString() 350 { 351 StringBuffer sbuf = new StringBuffer (); 352 353 sbuf.append("IntSet["); 354 for (int i = 1; i < size; i += 1) { 355 if (i != 1) 356 sbuf.append(" "); 357 358 sbuf.append(data[i - 1]); 359 if (data[i - 1] != data[i]) { 360 sbuf.append(","); 361 sbuf.append(data[i]); 362 } 363 } 364 sbuf.append("]"); 365 366 return sbuf.toString(); 367 } 368 369 372 public Object clone() 373 { 374 IntSet set = new IntSet(false); 375 376 set.data = new int[data.length]; 377 set.size = size; 378 379 System.arraycopy(data, 0, set.data, 0, size); 380 381 return set; 382 } 383 384 private IntSet(boolean dummy) { 385 } 386 387 390 public IntSet() { 391 data = new int[16]; 392 size = 0; 393 } 394 } 395 | Popular Tags |