Reputation: 2256
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
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
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
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
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
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