James P
James P

Reputation: 2256

Return contiguous 0's in a given binary number

I'm just working through some exercises in C#. I would like to return the number of contiguous 0's in given binary number. For example:

int test1 = 101010;  // Return 1
int test2 = 100101;  // Return 2
int test3 = 100001;  // Return 4
int test4 = 111111;  // Return 0

I have come up with the following code which works for tests 1,2 & 4 but not for test 3.

    public static int continuousZeros(int x)
    {

        char[] charArray = x.ToString().ToCharArray();

        int count = 0;
        int total = 0;

        for (int i = 0; i < charArray.Length; i++)
        {
            if (charArray[i] == '0' && charArray[i - 1] == '0')
            {
                count++; 
            }
            else if (charArray[i] == '0' && charArray[i - 1] == '1')
            {
                total = count + 1;
                count = 0;
            }
        }

        return total;
    }

If I try and add another else if: if (charArray[i] == '1' && charArray[i - 1] == '0') I get an IndexOutofRangeException.

I'm also sure there is a more efficient way to accomplish this?

Upvotes: 0

Views: 161

Answers (5)

Sami AlGhaberi
Sami AlGhaberi

Reputation: 19

I have made some modification to your code and it solved the problem, and gave the correct result

public static int continuousZeros(int x)
    {

        char[] charArray = x.ToString().ToCharArray();

        int count = 0;
        int total = 0;

        for (int i = 0; i < charArray.Length; i++)
        {
            if (charArray[i] == '0' )
            {
                count++;
            }
            else  
            {
                total = Math.Max(total,count);
                count = 0;
            }
        }

        return total;
    }

Upvotes: 0

Guffa
Guffa

Reputation: 700402

You don't need to look at combintations of bits, you can just count zero bits and whenever you find a one bit you compare the count to the highest count so far.

If you go through the bits from the lowest to the highest, there is always a one bit at the end, which means that there can't be a range of zero bits that you need to check after the loop. That will already have been taken care of when you encounter that last one bit.

You don't need to convert the number into a string, you can just pick the lowest bit until the remaining number is zero.

public static int continuousZeros(int x) {
  int count = 0;
  int highest = 0;
  while (x > 0) {
    if ((x & 1) == 0) {
      count++;
    } else {
      highest = Math.Max(count, highest);
      count = 0;
    }
    x >>= 1;
  }
  return highest;
}

Note: A number like 100001 is not a binary number, it's a decimal number that looks like a binary number. This solution handles actual binary numbers, i.e. the decimal representation of the binary number 100001 is 33.

Upvotes: 1

aquemini
aquemini

Reputation: 960

As others have mentioned, you're trying to access charArray[-1], which throws an exception. This was my first instinct:

public static int continuousZeros(int x)
{
    int max = 0;
    int current = 0;

    char[] charArray = x.ToString().ToCharArray();

    for (int i = 0; i < charArray.Length; i++)
    {
        if (charArray[i] == '0')
        {
            current++;
        }
        else
        {
            if (current > max) { max = current; }
            current = 0;
        }
    }

    return max;
}

Upvotes: 1

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

How about something like this ?

char[] charArray = x.ToString().ToCharArray();
bool zeroControl = false;
List<int> counts = new List<int>();
int currentCount = 0;
for (int i = 0; i < charArray.Length; i++)
{
    if (charArray[i] == '0' && !zeroControl)
    {
         zeroControl = true;
         currentCount++;
    }
    else if (charArray[i] == '0')
    {
         currentCount++;
    }
    else
    {
         zeroControl = false;
         counts.Add(currentCount);
         currentCount = 0;
    }
}
counts.Add(currentCount);
var result = counts.Max();

It doesn't look like so elegant but it works for all numbers.

Upvotes: 1

Grant Winney
Grant Winney

Reputation: 66459

I'm also sure there is a more efficient way to accomplish this?

You could use a simple LINQ statement:

var maxZeroesInString = myString.ToString().Split('1').Max(x => x.Length);

Assuming your string will only have 0 and 1, you can split on the 1. Now you have an array of strings that only consist of 0, so you can just find the longest one.

Upvotes: 2

Related Questions