BitSet.java
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:11k
源码类别:

编译器/解释器

开发平台:

Others

  1. package antlr.collections.impl;
  2. /* ANTLR Translator Generator
  3.  * Project led by Terence Parr at http://www.jGuru.com
  4.  * Software rights: http://www.antlr.org/RIGHTS.html
  5.  *
  6.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/collections/impl/BitSet.java#1 $
  7.  */
  8. import antlr.CharFormatter;
  9. /**A BitSet to replace java.util.BitSet.
  10.  * Primary differences are that most set operators return new sets
  11.  * as opposed to oring and anding "in place".  Further, a number of
  12.  * operations were added.  I cannot contain a BitSet because there
  13.  * is no way to access the internal bits (which I need for speed)
  14.  * and, because it is final, I cannot subclass to add functionality.
  15.  * Consider defining set degree.  Without access to the bits, I must
  16.  * call a method n times to test the ith bit...ack!
  17.  *
  18.  * Also seems like or() from util is wrong when size of incoming set is bigger
  19.  * than this.bits.length.
  20.  *
  21.  * @author Terence Parr, MageLang Institute
  22.  * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
  23.  */
  24. public class BitSet implements Cloneable {
  25. protected final static int BITS = 64;    // number of bits / long
  26. protected final static int NIBBLE = 4;
  27. protected final static int LOG_BITS = 6; // 2^6 == 64
  28. /* We will often need to do a mod operator (i mod nbits).  Its turns out
  29.  * that, for powers of two, this mod operation is same as (i & (nbits-1)).
  30.  * Since mod is slow, we use a precomputed mod mask to do the mod instead.
  31.  */
  32. protected final static int MOD_MASK = BITS-1;
  33. protected long bits[];
  34. /** Construct a bitset of size one word (64 bits) */
  35. public BitSet() {
  36. this(BITS);
  37. }
  38. /** Construction from a static array of longs */
  39. public BitSet(long[] bits_)
  40. {
  41. bits = bits_;
  42. }
  43. /** Construct a bitset given the size
  44.  * @param nbits The size of the bitset in bits
  45.  */
  46. public BitSet(int nbits) {
  47. bits = new long[((nbits-1) >> LOG_BITS) + 1];
  48. }
  49. // or this element into this set (grow as necessary to accommodate)
  50. public void add(int el) {
  51. //System.out.println("add("+el+")");
  52. int n = wordNumber(el);
  53. //System.out.println("word number is "+n);
  54. //System.out.println("bits.length "+bits.length);
  55. if (n >= bits.length) {
  56. growToInclude(el);
  57. }
  58. bits[n] |= bitMask(el);
  59. }
  60. public BitSet and(BitSet a) {
  61. BitSet s = (BitSet)this.clone();
  62. s.andInPlace(a);
  63. return s;
  64. }
  65. public void andInPlace(BitSet a) {
  66. int min = Math.min(bits.length, a.bits.length);
  67. for (int i = min-1; i >= 0; i--) {
  68. bits[i] &= a.bits[i];
  69. }
  70. // clear all bits in this not present in a (if this bigger than a).
  71. for (int i = min; i < bits.length ; i++) {
  72. bits[i] = 0;
  73. }
  74. }
  75. private final long bitMask(int bitNumber) {
  76. int bitPosition = bitNumber&MOD_MASK; // bitNumber mod BITS
  77. return 1L << bitPosition;
  78. }
  79. public void clear() {
  80. for (int i = bits.length-1; i >= 0; i--) {
  81. bits[i] = 0;
  82. }
  83. }
  84. public void clear(int el) {
  85. int n = wordNumber(el);
  86. if (n >= bits.length) { // grow as necessary to accommodate
  87. growToInclude(el);
  88. }
  89. bits[n] &= ~bitMask(el);
  90. }
  91. public Object clone() {
  92. BitSet s;
  93. try {
  94. s = (BitSet)super.clone();
  95. s.bits = new long[bits.length];
  96. System.arraycopy(bits, 0, s.bits, 0, bits.length);
  97. }
  98. catch (CloneNotSupportedException e) {
  99. throw new InternalError();
  100. }
  101. return s;
  102. }
  103. public int degree() {
  104. int deg = 0;
  105. for (int i=bits.length-1; i>=0; i--) {
  106. long word = bits[i];
  107. if (word != 0L) {
  108. for (int bit=BITS-1; bit>=0; bit--) {
  109. if ( (word & (1L << bit)) != 0 ) {
  110. deg++;
  111. }
  112. }
  113. }
  114. }
  115. return deg;
  116. }
  117. // code "inherited" from java.util.BitSet
  118. public boolean equals(Object obj) {
  119. if ((obj != null) && (obj instanceof BitSet)) {
  120. BitSet set = (BitSet)obj;
  121. int n = Math.min(bits.length, set.bits.length);
  122. for (int i = n ; i-- > 0 ;) {
  123. if (bits[i] != set.bits[i]) {
  124. return false;
  125. }
  126. }
  127. if (bits.length > n) {
  128. for (int i = bits.length ; i-- > n ;) {
  129. if (bits[i] != 0) {
  130. return false;
  131. }
  132. }
  133. } else if (set.bits.length > n) {
  134. for (int i = set.bits.length ; i-- > n ;) {
  135. if (set.bits[i] != 0) {
  136. return false;
  137. }
  138. }
  139. }
  140. return true;
  141. }
  142. return false;
  143. }
  144. /** Find ranges in a set element array.
  145.  * @param elems The array of elements representing the set, usually from Bit
  146. Set.toArray().
  147.  * @return Vector of ranges.
  148.  */
  149. public static Vector getRanges(int[] elems) {
  150. if (elems.length==0) {
  151. return null;
  152. }
  153. int begin = elems[0];
  154. int end = elems[elems.length-1];
  155. if ( elems.length<=2 ) {
  156. // Not enough elements for a range expression
  157. return null;
  158. }
  159. Vector ranges = new Vector(5);
  160. // look for ranges
  161. for (int i=0; i<elems.length-2; i++) {
  162. int lastInRange;
  163. lastInRange = elems.length-1;
  164. for (int j=i+1; j<elems.length; j++) {
  165. if ( elems[j] != elems[j-1]+1 ) {
  166. lastInRange = j-1;
  167. break;
  168. }
  169. }
  170. // found a range
  171. if ( lastInRange-i > 2 ) {
  172. ranges.appendElement(new IntRange(elems[i],elems[lastInRange]));
  173. }
  174. }
  175. return ranges;
  176. }
  177. /**
  178.  * Grows the set to a larger number of bits.
  179.  * @param bit element that must fit in set
  180.  */
  181. public void growToInclude(int bit) {
  182. int newSize = Math.max(bits.length<<1, numWordsToHold(bit));
  183. long newbits[] = new long[newSize];
  184. System.arraycopy(bits, 0, newbits, 0, bits.length);
  185. bits = newbits;
  186. }
  187. public boolean member(int el) {
  188. int n = wordNumber(el);
  189. if (n >= bits.length) return false;
  190. return (bits[n] & bitMask(el)) != 0;
  191. }
  192. public boolean nil() {
  193. for (int i=bits.length-1; i>=0; i--) {
  194. if ( bits[i]!=0 ) return false;
  195. }
  196. return true;
  197. }
  198. public BitSet not() {
  199. BitSet s = (BitSet)this.clone();
  200. s.notInPlace();
  201. return s;
  202. }
  203. public void notInPlace() {
  204. for (int i = bits.length-1; i >= 0; i--) {
  205. bits[i] = ~bits[i];
  206. }
  207. }
  208. /** complement bits in the range 0..maxBit. */
  209. public void notInPlace(int maxBit) {
  210. notInPlace(0, maxBit);
  211. }
  212. /** complement bits in the range minBit..maxBit.*/
  213. public void notInPlace(int minBit, int maxBit) {
  214. // make sure that we have room for maxBit
  215. growToInclude(maxBit);
  216. for (int i = minBit; i <= maxBit; i++) {
  217. int n = wordNumber(i);
  218. bits[n] ^= bitMask(i);
  219. }
  220. }
  221. private final int numWordsToHold(int el) {
  222. return (el>>LOG_BITS) + 1;
  223. }
  224. public static BitSet of(int el) {
  225. BitSet s = new BitSet(el+1);
  226. s.add(el);
  227. return s;
  228. }
  229. /** return this | a in a new set */
  230. public BitSet or(BitSet a) {
  231. BitSet s = (BitSet)this.clone();
  232. s.orInPlace(a);
  233. return s;
  234. }
  235. public void orInPlace(BitSet a) {
  236. // If this is smaller than a, grow this first
  237. if ( a.bits.length > bits.length ) {
  238. setSize(a.bits.length);
  239. }
  240. int min = Math.min(bits.length, a.bits.length);
  241. for (int i = min-1; i >= 0; i--) {
  242. bits[i] |= a.bits[i];
  243. }
  244. }
  245. // remove this element from this set
  246. public void remove(int el) {
  247. int n = wordNumber(el);
  248. if (n >= bits.length) {
  249. growToInclude(el);
  250. }
  251. bits[n] &= ~bitMask(el);
  252. }
  253. /**
  254.  * Sets the size of a set.
  255.  * @param nwords how many words the new set should be
  256.  */
  257. private void setSize(int nwords) {
  258. long newbits[] = new long[nwords];
  259. int n = Math.min(nwords, bits.length);
  260. System.arraycopy(bits, 0, newbits, 0, n);
  261. bits = newbits;
  262. }
  263. public int size() {
  264. return bits.length << LOG_BITS; // num words * bits per word
  265. }
  266. /**Is this contained within a? */
  267. public boolean subset(BitSet a) {
  268. if ( a==null || !(a instanceof BitSet) ) return false;
  269. return this.and(a).equals(this);
  270. }
  271. /**Subtract the elements of 'a' from 'this' in-place.
  272.  * Basically, just turn off all bits of 'this' that are in 'a'.
  273.  */
  274. public void subtractInPlace(BitSet a) {
  275. if ( a==null ) return;
  276. // for all words of 'a', turn off corresponding bits of 'this'
  277. for (int i = 0; i<bits.length&&i<a.bits.length; i++) {
  278. bits[i] &= ~a.bits[i];
  279. }
  280. }
  281. public int[] toArray() {
  282. int[] elems = new int[degree()];
  283. int en = 0;
  284. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  285. if (member(i)) {
  286. elems[en++] = i;
  287. }
  288. }
  289. return elems;
  290. }
  291. public String toString() {
  292. return toString(",");
  293. }
  294. /** Transform a bit set into a string by formatting each element as an integer
  295.  * @separator The string to put in between elements
  296.  * @return A commma-separated list of values
  297.  */
  298. public String toString(String separator) {
  299. String str = "";
  300. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  301. if (member(i)) {
  302. if (str.length() > 0) {
  303. str += separator;
  304. }
  305. str = str + i;
  306. }
  307. }
  308. return str;
  309. }
  310. /** Transform a bit set into a string of characters.
  311.  * @separator The string to put in between elements
  312.  * @param formatter An object implementing the CharFormatter interface.
  313.  * @return A commma-separated list of character constants.
  314.  */
  315. public String toString(String separator, CharFormatter formatter) {
  316. String str = "";
  317. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  318. if (member(i)) {
  319. if (str.length() > 0) {
  320. str += separator;
  321. }
  322. str = str + formatter.literalChar(i);
  323. }
  324. }
  325. return str;
  326. }
  327. /**Create a string representation where instead of integer elements, the
  328.  * ith element of vocabulary is displayed instead.  Vocabulary is a Vector
  329.  * of Strings.
  330.  * @separator The string to put in between elements
  331.  * @return A commma-separated list of character constants.
  332.  */
  333. public String toString(String separator, Vector vocabulary) {
  334. if ( vocabulary == null ) {
  335. return toString(separator);
  336. }
  337. String str = "";
  338. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  339. if (member(i)) {
  340. if (str.length() > 0) {
  341. str += separator;
  342. }
  343. if ( i>=vocabulary.size() ) {
  344. str += "<bad element "+i+">";
  345. }
  346. else if ( vocabulary.elementAt(i)==null ) {
  347. str += "<"+i+">";
  348. }
  349. else {
  350. str += (String)vocabulary.elementAt(i);
  351. }
  352. }
  353. }
  354. return str;
  355. }
  356. /**
  357.  * Dump a comma-separated list of the words making up the bit set.
  358.  * Split each 64 bit number into two more manageable 32 bit numbers.
  359.  * This generates a comma-separated list of C++-like unsigned long constants.
  360.  */
  361. public String toStringOfHalfWords()
  362. {
  363. String s = new String();
  364. for (int i = 0; i < bits.length; i++)
  365. {
  366. if (i!=0) s += ", ";
  367. long tmp = bits[i];
  368. tmp &= 0xFFFFFFFFL;
  369. s += (tmp + "UL");
  370. s += ", ";
  371. tmp = bits[i]>>>32;
  372. tmp &= 0xFFFFFFFFL;
  373. s += (tmp + "UL");
  374. }
  375. return s;
  376. }
  377. /** 
  378.  * Dump a comma-separated list of the words making up the bit set.
  379.  * This generates a comma-separated list of Java-like long int constants.
  380.  */
  381. public String toStringOfWords()
  382. {
  383. String s = new String();
  384. for (int i = 0; i < bits.length; i++)
  385. {
  386. if (i!=0) s += ", ";
  387. s += (bits[i] + "L");
  388. }
  389. return s;
  390. }
  391. /** Print out the bit set but collapse char ranges.
  392.  */
  393. public String toStringWithRanges(String separator, CharFormatter formatter) {
  394. String str = "";
  395. int[] elems = this.toArray();
  396. if (elems.length==0) {
  397. return "";
  398. }
  399. // look for ranges
  400. int i=0;
  401. while (i<elems.length) {
  402. int lastInRange;
  403. lastInRange = 0;
  404. for (int j=i+1; j<elems.length; j++) {
  405. if ( elems[j] != elems[j-1]+1 ) {
  406. break;
  407. }
  408. lastInRange = j;
  409. }
  410. // found a range
  411. if (str.length() > 0) {
  412. str += separator;
  413. }
  414. if ( lastInRange-i >= 2 ) {
  415. str += formatter.literalChar(elems[i]);
  416. str += "..";
  417. str += formatter.literalChar(elems[lastInRange]);
  418. i = lastInRange; // skip past end of range for next range
  419. }
  420. else { // no range, just print current char and move on
  421. str += formatter.literalChar(elems[i]);
  422. }
  423. i++;
  424. }
  425. return str;
  426. }
  427. private final int wordNumber(int bit) {
  428. return bit>>LOG_BITS; // bit / BITS
  429. }
  430. }