示例#1
0
        /// <summary>
        /// Applies a procedure to each coordinate that holds a bit in the given state.
        /// Iterates rowwise downwards from [columns()-1,rows()-1] to [0,0].
        /// Useful, for example, if you want to copy bits into an image or somewhere else.
        /// Optimized for speedd Particularly quick if one of the following conditions holds
        /// <ul>
        /// <li><i>state==true</i> and the receiver is sparse (<i>cardinality()</i> is small compared to <i>Size</i>).
        /// <li><i>state==false</i> and the receiver is dense (<i>cardinality()</i> is large compared to <i>Size</i>).
        /// </ul>
        /// </summary>
        /// <param name="state">element to search for.</param>
        /// <param name="procedure">a procedure object taking as first argument the current column and as second argument the current rowd Stops iteration if the procedure returns <i>false</i>, otherwise continuesd </param>
        /// <returns><i>false</i> if the procedure stopped before all elements where iterated over, <i>true</i> otherwised </returns>
        public Boolean ForEachCoordinateInState(Boolean state, Cern.Colt.Function.IntIntProcedure procedure)
        {
            /*
             * this is equivalent to the low level version below, apart from that it iterates in the reverse oder and is slower.
             * if (Size==0) return true;
             * BitVector vector = toBitVector();
             * return vector.forEachIndexFromToInState(0,Size-1,state,
             *  new cern.colt.function.IntFunction() {
             *      public Boolean apply(int index) {
             *          return function.apply(index%columns, index/columns);
             *      }
             *  }
             * );
             */

            //low level implementation for speed.
            if (Size == 0)
            {
                return(true);
            }
            BitVector vector = new BitVector(_bits, Size);

            long[] theBits = _bits;

            int column = _columns - 1;
            int row    = _rows - 1;

            // for each coordinate of bits of partial unit
            long val = theBits[_bits.Length - 1];

            for (int j = vector.NumberOfBitsInPartialUnit(); --j >= 0;)
            {
                long mask = val & (1L << j);
                if ((state && (mask != 0L)) || ((!state) && (mask == 0L)))
                {
                    if (!procedure(column, row))
                    {
                        return(false);
                    }
                }
                if (--column < 0)
                {
                    column = _columns - 1;
                    --row;
                }
            }


            // for each coordinate of bits of full units
            int  bitsPerUnit = QuickBitVector.BITS_PER_UNIT;
            long comparator;

            if (state)
            {
                comparator = 0L;
            }
            else
            {
                comparator = ~0L;  // all 64 bits set
            }
            for (int i = vector.NumberOfFullUnits(); --i >= 0;)
            {
                val = theBits[i];
                if (val != comparator)
                {
                    // at least one element within current unit matches.
                    // iterate over all bits within current unit.
                    if (state)
                    {
                        for (int j = bitsPerUnit; --j >= 0;)
                        {
                            if (((val & (1L << j))) != 0L)
                            {
                                if (!procedure(column, row))
                                {
                                    return(false);
                                }
                            }
                            if (--column < 0)
                            {
                                column = _columns - 1;
                                --row;
                            }
                        }
                    }
                    else
                    { // unrolled comparison for speed.
                        for (int j = bitsPerUnit; --j >= 0;)
                        {
                            if (((val & (1L << j))) == 0L)
                            {
                                if (!procedure(column, row))
                                {
                                    return(false);
                                }
                            }
                            if (--column < 0)
                            {
                                column = _columns - 1;
                                --row;
                            }
                        }
                    }
                }
                else
                { // no element within current unit matches --> skip unit
                    column -= bitsPerUnit;
                    if (column < 0)
                    {
                        // avoid implementation with *, /, %
                        column += bitsPerUnit;
                        for (int j = bitsPerUnit; --j >= 0;)
                        {
                            if (--column < 0)
                            {
                                column = _columns - 1;
                                --row;
                            }
                        }
                    }
                }
            }

            return(true);
        }