Reputation: 49
I have a string {101110111010001111} I'm searching for the total number of all sequences of equal bits with an exact length of 3 bits. In above string the answer willbe 3 (please note that the last one "1111" doesn't count as it has more than 3 equal bits. Any suggestions how to do this?
Upvotes: 0
Views: 151
Reputation: 2818
An algorithmic solution. Checks for any n consecutive characters. But this is not completely tested for all negative scenarios.
public static int GetConsecutiveCharacterCount(this string input, int n)
{
// Does not contain expected number of characters
if (input.Length < n || n < 1)
return 0;
return Enumerable.Range(0, input.Length - (n - 1)) // Last n-1 characters will be covered in the last but one iteration.
.Where(x => Enumerable.Range(x, n).All(y => input[x] == input[y]) && // Check whether n consecutive characters match
((x - 1) > -1 ? input[x] != input[x - 1] : true) && // Compare the previous character where applicable
((x + n) < input.Length ? input[x] != input[x + n] : true) // Compare the next character where applicable
)
.Count();
}
Upvotes: 0
Reputation: 2586
Yet another approach: Since you are only counting bits, you can split the string by "1" and "0" and then count all elements with lenght 3:
string inputstring = "101110111010001111";
string[] str1 = inputstring.Split('0');
string[] str2 = inputstring.Split('1');
int result = str1.Where(s => s.Length == 3).Count() + str2.Where(s => s.Length == 3).Count();
return result
Upvotes: 0
Reputation: 1
You can split the string by "111" to get an array. You can then simply count the lines that not begins with "1" with the linq.
See the sample:
using System;
using System.Linq;
namespace experiment
{
class Program
{
static void Main(string[] args)
{
string data = "{101110111010001111}";
string[] sequences = data.Split(new string[] {"111"}, StringSplitOptions.None);
int validCounts = sequences.Count(i => i.Substring(0, 1) != "1");
Console.WriteLine("Count of sequences: {0}", validCounts);
// See the splited array
foreach (string item in sequences) {
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
Upvotes: 0
Reputation:
Is it that you need? Sometimes the simplest solutions are the best:
public static int Count(string txt)
{
// TODO validation etc
var result = 0;
char lstChr = txt[0];
int lastChrCnt = 1;
for (var i = 1; i < txt.Length; i++)
{
if (txt[i] == lstChr)
{
lastChrCnt += 1;
}
else
{
if (lastChrCnt == 3)
{
result += 1;
}
lstChr = txt[i];
lastChrCnt = 1;
}
}
return lastChrCnt == 3 ? result + 1 : result;
}
Upvotes: 1
Reputation: 39284
If you don't want a simple solution, try this:
string s = "1101110111010001111";
var regex = new Regex(@"(.)\1+");
var matches = regex.Matches(s);
int count = matches.Cast<Match>().Where(x => x.Length == 3).Count();
Explanation:
Upvotes: 5
Reputation: 391336
You can use a regular expression:
Regex.Matches(s, @"((?<=0)|^)111((?=0)|$)|((?<=1)|^)000((?=1)|$)");
Here's the same expression with comments:
Regex.Matches(s, @"
(
(?<=0) # is preceeded by a 0
| # or
^ # is at start
)
111 # 3 1's
(
(?=0) # is followed by a 0
| # or
$ # is at start
)
| # - or -
(
(?<=1) # is preceeded by a 1
| # or
^ # is at start
)
000 # 3 0's
(
(?=1) # followed by a 1
| # or
$ # is at end
)", RegexOptions.IgnorePatternWhitespace).Dump();
Upvotes: 1