Yulia Genova
Yulia Genova

Reputation: 49

Count consequitive numbers in a string C#

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

Answers (6)

Parthasarathy
Parthasarathy

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

H W
H W

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

ByPS
ByPS

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

user2160375
user2160375

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

Hans Kesting
Hans Kesting

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:

  • The regex finds sets of 2 or more identical characters (not limited to 0's and 1's)
  • Then only sets of exactly 3 characters are counted

Upvotes: 5

Lasse V. Karlsen
Lasse V. Karlsen

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

Related Questions