001 package org.jaga.util;
002
003
004
005 /**
006 * TODO: Complete these comments.
007 *
008 * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
009 *
010 * <p><u>Company:</u> University College London and JAGA.Org
011 * (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
012 * </p>
013 *
014 * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
015 * This program is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU General Public License as published by
017 * the Free Software Foundation, ONLY if you include a note of the original
018 * author(s) in any redistributed/modified copy.<br/>
019 * This program is distributed in the hope that it will be useful,
020 * but WITHOUT ANY WARRANTY; without even the implied warranty of
021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
022 * GNU General Public License for more details.<br/>
023 * You should have received a copy of the GNU General Public License
024 * along with this program; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
026 * or see http://www.gnu.org/licenses/gpl.html</p>
027 *
028 * @author Greg Paperin (greg@jaga.org)
029 *
030 * @version JAGA public release 1.0 beta
031 */
032
033 public class BitString {
034
035 private int length;
036 private int [] content = null;
037
038 private BitString() {
039 throw new UnsupportedOperationException("Use BitString(int)");
040 }
041
042 public BitString(int length) {
043 this.length = length;
044 int bufSize = length / 32;
045 if (0 != length % 32)
046 ++bufSize;
047 content = new int[bufSize];
048 for (int i = 0; i < bufSize; content[i++] = 0);
049 }
050
051 public BitString(final BitString toCopy) {
052 this.length = toCopy.length;
053 int bufSize = length / 32;
054 if (0 != length % 32)
055 ++bufSize;
056 this.content = new int[bufSize];
057 System.arraycopy(toCopy.content, 0, this.content, 0, this.content.length);
058 }
059
060 public Object clone() {
061 BitString copy = new BitString(this.length);
062 System.arraycopy(this.content, 0, copy.content, 0, copy.content.length);
063 return copy;
064 }
065
066 public int getLength() {
067 return length;
068 }
069
070 public BitString substring(int from, int to) {
071 int len = checkSubLength(from, to);
072 BitString substring = new BitString(len);
073 for (int i = from; i < to; i++)
074 substring.setUnchecked(i - from, this.getUnchecked(i));
075 return substring;
076 }
077
078 public boolean get(int index) {
079 checkIndex(index);
080 return getUnchecked(index);
081 }
082
083 protected boolean getUnchecked(int index) {
084 int segment = index / 32;
085 int offset = index % 32;
086 int mask = 0x1 << (32 - offset - 1);
087 return 0 != (content[segment] & mask);
088 }
089
090 public void set(int index, boolean value) {
091 checkIndex(index);
092 setUnchecked(index, value);
093 }
094
095 public void setUnchecked(int index, boolean value) {
096 int segment = index / 32;
097 int offset = index % 32;
098 int mask = 0x1 << (32 - offset - 1);
099 if (value)
100 content[segment] |= mask;
101 else
102 content[segment] &= ~mask;
103 }
104
105 public void set(int from, int to, boolean value) {
106 checkSubLength(from, to);
107 for (int i = from; i < to; setUnchecked(i++, value));
108 }
109
110 public void set(int from, int to, BitString values) {
111 if (values.getLength() == 0)
112 throw new IllegalArgumentException("Length of values must be > 0");
113 int len = checkSubLength(from, to);
114 int iV = 0;
115 for (int i = from; i < to; i++, iV++) {
116 if (iV >= values.getLength())
117 iV = 0;
118 this.setUnchecked(i, values.getUnchecked(iV));
119 }
120 }
121
122 public void flip(int index) {
123 checkIndex(index);
124 int segment = index / 32;
125 int offset = index % 32;
126 int mask = 0x1 << (32 - offset - 1);
127 content[segment] ^= mask;
128 }
129
130 public String toString() {
131 StringBuffer s = new StringBuffer(length);
132 for (int i = 0; i < length; s.append(get(i++) ? 1 : 0));
133 return s.toString();
134 }
135
136 protected int checkSubLength(int from, int to) throws IndexOutOfBoundsException {
137 checkIndex(from);
138 checkIndex(to - 1);
139 int sublen = to - from;
140 if (0 > sublen)
141 throw new IllegalArgumentException("must have 'from' <= 'to', but has "
142 + from + " > " + to);
143 return sublen;
144 }
145
146 protected void checkIndex(int index) throws IndexOutOfBoundsException {
147 if (index < 0 || index >= this.length)
148 throw new IndexOutOfBoundsException("index is " + index
149 + ", but must be in [0, "
150 + (this.length - 1) + "]");
151 }
152 }