public BitString(BitString bits) { if (bits == null) { throw new ArgumentNullException("bits"); } _length = bits._length; _array = new long[(_length + 63)/64]; MinPositiveWord = bits.MinPositiveWord; MaxPositiveWord = bits.MaxPositiveWord; if (_array.Length == 1) { _array[0] = bits._array[0]; } else { Array.Copy(bits._array, _array, _array.Length); } }
private void checkOperand(BitString operand) { if (operand == null) { throw new ArgumentNullException(); } if (operand._length != _length) { throw new ArgumentException(); } }
public BitString Xor(BitString value) { checkOperand(value); int ints = (_length + 63)/64; for (int i = 0; i < ints; i++) { _array[i] ^= value._array[i]; RefreshBordersByWord(i); } _version++; return this; }
public BitString Or(BitString value) { //var sw = Stopwatch.StartNew(); checkOperand(value); int ints = (_length + 63)/64; for (int i = 0; i < ints; i++) { _array[i] |= value._array[i]; RefreshBordersByWord(i); } _version++; //Console.WriteLine("OR -> Len: {0}, Time: {1}", this._array.Length, sw.Elapsed.TotalMilliseconds); return this; }
public bool HaveCommonBits(BitString other) { if (Length != other.Length) { throw new ArgumentException("Bit strings must have same size", "other"); } //var sw = Stopwatch.StartNew(); int from = Math.Max(MinPositiveWord, other.MinPositiveWord); int to = Math.Min(MaxPositiveWord, other.MaxPositiveWord); bool result = false; int steps = 0; long[] otherArray = other._array; for (int i = from; i <= to; i++) { steps++; long v1 = _array[i]; long v2 = otherArray[i]; if (v1 != 0 && v2 != 0 && ((v1 & v2) != 0)) { result = true; break; } } /* if (sw.Elapsed.TotalMilliseconds > 0.1) { Console.WriteLine("HCB -> Min: {0}, Max: {1}, Delta: {2}, Steps: {3}, Time: {4}", from, to, to - from, steps, sw.Elapsed.TotalMilliseconds); } */ return result; }
public int GetLastCommonBitIndex(BitString other) { if (Length != other.Length) { throw new ArgumentException("Bit strings must have same size", "other"); } int from = Math.Max(MinPositiveWord, other.MinPositiveWord); int to = Math.Min(MaxPositiveWord, other.MaxPositiveWord); long[] otherArray = other._array; for (int i = from; i <= to; i++) { long v1 = _array[i]; long v2 = otherArray[i]; long n = v1 & v2; if (n != 0) { List<byte> bits1 = BitSetsIn16Bits[(int) (n & 0xffffu)]; List<byte> bits2 = BitSetsIn16Bits[(int) ((n >> 16) & 0xffffu)]; List<byte> bits3 = BitSetsIn16Bits[(int) ((n >> 32) & 0xffffu)]; List<byte> bits4 = BitSetsIn16Bits[(int) ((n >> 48) & 0xffffu)]; if (bits4.Count > 0) { return bits4[bits4.Count - 1] + 48 + i*64; } if (bits3.Count > 0) { return bits3[bits3.Count - 1] + 32 + i*64; } if (bits2.Count > 0) { return bits2[bits2.Count - 1] + 16 + i*64; } return bits1[bits1.Count - 1] + i*64; } } return -1; }
public List<int> GetCommonIndices(BitString other) { if (Length != other.Length) { throw new ArgumentException("Bit strings must have same size", "other"); } int from = Math.Max(MinPositiveWord, other.MinPositiveWord); int to = Math.Min(MaxPositiveWord, other.MaxPositiveWord); var result = new List<int>(); long[] otherArray = other._array; for (int i = from; i <= to; i++) { long v1 = _array[i]; long v2 = otherArray[i]; long n = v1 & v2; if (n != 0) { List<byte> bits1 = BitSetsIn16Bits[(int) (n & 0xffffu)]; List<byte> bits2 = BitSetsIn16Bits[(int) ((n >> 16) & 0xffffu)]; List<byte> bits3 = BitSetsIn16Bits[(int) ((n >> 32) & 0xffffu)]; List<byte> bits4 = BitSetsIn16Bits[(int) ((n >> 48) & 0xffffu)]; if (bits1.Count > 0) { result.Add(bits1[0] + i*64); } else if (bits2.Count > 0) { result.Add(bits2[0] + 16 + i*64); } else if (bits3.Count > 0) { result.Add(bits3[0] + 32 + i*64); } else { result.Add(bits4[0] + 48 + i*64); } } } return result; }
public int CountCommonBits(BitString other) { if (Length != other.Length) { throw new ArgumentException("Bit strings must have same size", "other"); } int from = Math.Max(MinPositiveWord, other.MinPositiveWord); int to = Math.Min(MaxPositiveWord, other.MaxPositiveWord); int result = 0; long[] otherArray = other._array; for (int i = from; i <= to; i++) { long v1 = _array[i]; long v2 = otherArray[i]; long n = v1 & v2; if (n != 0) { List<byte> bits1 = BitSetsIn16Bits[(int) (n & 0xffffu)]; List<byte> bits2 = BitSetsIn16Bits[(int) ((n >> 16) & 0xffffu)]; List<byte> bits3 = BitSetsIn16Bits[(int) ((n >> 32) & 0xffffu)]; List<byte> bits4 = BitSetsIn16Bits[(int) ((n >> 48) & 0xffffu)]; result += bits1.Count + bits2.Count + bits3.Count + bits4.Count; } } return result; }