Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting the amount of repetitions a letter has in a string

I'm working on a Kata on CodeWars in which I have to count the amount of repetitions each letter has in a string. The amount of repetitions should be stored in an int array.

The algorithm I've written seems to almost work, however I get a weird output that I can't explain. I might be missing something in the code.

static void Main(string[] args)
{
    string str = "abcdef";
    string input = str.ToLower();
    int count = 0;

    string[] arrayInput = Regex.Split(input, string.Empty);
    string[] alphabet = Regex.Split("abcdefghijklmnopqrstuvwxyz", string.Empty);
    int[] amounts = new int[input.Length];

    foreach (string letter in alphabet)
    {
        for (int x = 0; x < input.Length; x++)
        {
            if (arrayInput[x] == letter)
            {
               amounts[x]++;
            }
        }
    }

    foreach (int amount in amounts)
    {
        Console.Write(amount + ", ");
    }
    Console.ReadKey();
}

Output:

"2, 1, 1, 1, 1, 1,"

Expected:

"1, 1, 1, 1, 1, 1,"

since each letter only appears once in the string.

like image 853
bezunyl Avatar asked Jul 31 '19 14:07

bezunyl


2 Answers

When querying, Linq often is good choice:

  using System.Linq;

  ...

  string str = "abcdef";

  // {1, 1, 1, 1, 1, 1} - each letter appears once 
  int[] result = str
    .ToLower()
  //.Where(c => c >= 'a' && c <= 'z') // uncomment, if we want 'a'..'z' range only 
    .GroupBy(c => c)
    .Select(group => group.Count())
    .ToArray();

  Console.Write(string.Join(", ", result));
like image 189
Dmitry Bychenko Avatar answered Sep 25 '22 07:09

Dmitry Bychenko


I think you have made a mistake:

int[] amounts = new int[input.Length];

Should be

int[] amounts = new int[26];

And also your loops aren't quite right.

You don't need to split the strings into string arrays. You can just use the string iterator to get each char. Also, if you were doing this on very large strings your solution would be inefficient as for every char you are iterating through the entire alphabet which isn't needed.

you can simplify what you've written considerably:

string input = "abcdef";
int[] counts = new int[26]; 
foreach (var ch in input)
{
    var c = char.ToLower(ch);
    if (c >= 'a' && c <= 'z')
        counts[c - 'a']++;
}
like image 43
Tim Rutter Avatar answered Sep 22 '22 07:09

Tim Rutter