简体   繁体   中英

Efficiently find ranges of consecutive non-set bits in BitSet

I'm trying to represent calendar available/unavailable slots for a particular day with each bit representing 15mins using BitSet. The bits which are set represent blocked calendar events. For getting the the slots which are free, I need to find the ranges where bits are not set.

I have the following BitSet

00000000000000000011111001000000000011100000000000000000011000

How to efficiently find the ranges of bits which are not set. In this case (1,18) and (24,25) and (27,36) etc.

Below is the current code I have written, which I feel is not efficient and also not clean.

int startIndex = -1;
int nextIndex = -1;
for(int i = getSlotIndex(currentWorkingStartDate); i <= getSlotIndex(currentWorkingEndDate); i++) {
    if(!matrix.get(i)) {
        if(startIndex == -1) {
            startIndex = i;
            nextIndex = i;
        }else {
            nextIndex = i;
        }
    }else if(startIndex != -1){

        ZonedDateTime availableStartDate = day.plusHours((startIndex/4)).plusMinutes(startIndex%4 * 15);
        ZonedDateTime availableEndDate = availableStartDate.plusMinutes((nextIndex - startIndex + 1) * 15L);
        currAvailabilitySlots.addAll(
                getSlotsBasedOnDurationWithTimeZone(new SlotModel(availableStartDate,availableEndDate),durationOfSlot,candidateTimeZoneId));
        startIndex = -1;
        nextIndex = -1;
    }
}

if(startIndex != -1) {
    ZonedDateTime availableStartDate = day.plusHours((startIndex/4)).plusMinutes(startIndex%4 * 15);
    ZonedDateTime availableEndDate = availableStartDate.plusMinutes((nextIndex - startIndex) * 15L);
    currAvailabilitySlots.addAll(
            getSlotsBasedOnDurationWithTimeZone(new SlotModel(availableStartDate,availableEndDate),durationOfSlot,candidateTimeZoneId));
}

There is a method for getting the next unset bit at or after a given index: BitSet.nextClearBit(int) .

There is a complementary method, nextSetBit(int) , for finding the next set bit.

So, you can find the start of a range with the former, and the end of the range with the latter.

You need to handle the return values of the methods carefully:

  • If nextSetBit returns -1, that means that the current run of clear bits extends to the end of the BitSet.
  • nextClearBit doesn't return -1, because BitSets don't have a clearly-defined size in terms of the number of clear bits - they essentially extend infinitely, but only actually allocate storage to hold set bits. So, if nextClearBit returns a value beyond the logical size of the BitSet (ie an index for a 15-minute slot beyond the end of the day/date range), you know that you can stop searching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM