Find the vowels in a string with C# .NET

Here comes a classic developer interview question: write a function that accepts a string and returns the number of vowels that it contains. The vowels in the English language are the following: a, e, i, o u. We want the vowel search to be case-insensitive, i.e. AEIOU must also be counted. This should be a fairly simple problem with multiple solutions. We’ll look at three of them in this post but there are certainly more:

  • using a counter
  • using a regex
  • LINQ

Let’s start with the class skeleton:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace Algorithms
{
    public class CountVowels
    {
        public int FindVowels(string input)
        {
            return 0;
        }        
    }
}

Here comes a short set of unit tests:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Algorithms;

namespace Algorithms.Tests
{
    [TestClass]
    public class CountVowelsTests
    {
        [TestMethod]
        public void CountVowelsTest()
        {
            var findVowels = new CountVowels();
            Assert.AreEqual(0, findVowels.FindVowels(null));
            Assert.AreEqual(3, findVowels.FindVowels("Hello World!!!"));
            Assert.AreEqual(5, findVowels.FindVowels("afdfgehhiddfgOdfgdU"));
            Assert.AreEqual(3, findVowels.FindVowels("UOE"));
            Assert.AreEqual(0, findVowels.FindVowels("rtyplkjhgfdszxcvb"));
        }
    }
}

Let’s start with the most basic counter-based solution that most developers came across in an intro course:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace Algorithms
{
    public class CountVowels
    {
        public int FindVowels(string input)
        {
            return FindVowelsWithHelpArray(input);            
        }

        private int FindVowelsWithHelpArray(String inputString)
        {
            int vowelCounter = 0;

            if (inputString != null)
            {
                var vowels = new List<char>() { 'a', 'e', 'i', 'o', 'u' };
                foreach (char c in inputString.ToLower())
                {
                    if (vowels.Contains(c))
                    {
                        vowelCounter++;
                    }
                }
            }            

            return vowelCounter;
        }        
    }
}

We initialise the counter variable vowelCounter to 0. Then if the input string is not null then we create a list of chars to contain all the vowels we want to count. Then we iterate through the lower-cased string char by char and if the current char is part of the vowel list then we increase the counter. Finally we return the counter from the function.

Run the unit tests, they all pass.

Next, let’s take a look at the Regex solution:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace Algorithms
{
    public class CountVowels
    {
        public int FindVowels(string input)
        {
           //return FindVowelsWithHelpArray(input);
           return FindVowelsWithRegex(input);
        }

        private int FindVowelsWithHelpArray(String inputString)
        {
            abridged...
        }

        private int FindVowelsWithRegex(String inputString)
        {
            if (inputString == null) return 0;
            return Regex.Matches(inputString, "[aeiou]", RegexOptions.IgnoreCase).Count;
        }        
    }
}

We use the Regex.Matches (https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.matches?view=netcore-3.1) function to count all the matches in the incoming string. The match is based on a simple array that reflects the vowels that we want to find. I took a shortcut and added the built-in RegexOptions enumeration to make sure that the search is case-insensitive instead of expressing it directly in the Regex string.

Run the unit tests, they will all still pass.

Finally let’s see a LINQ-based solution. LINQ is very versatile and there are certainly multiple ways to solve this problem using LINQ expressions. We’ll go for the most straightforward one using the Count() function:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace Algorithms
{
    public class CountVowels
    {
        public int FindVowels(string input)
        {
           //return FindVowelsWithHelpArray(input);
           //return FindVowelsWithRegex(input);
           return FindVowelsWithLinq(input);
        }

        private int FindVowelsWithHelpArray(String inputString)
        {
            abridged
        }

        private int FindVowelsWithRegex(String inputString)
        {
            abridged
        }

        private int FindVowelsWithLinq(String inputString)
        {
            if (inputString == null) return 0;
            var vowels = new List<char>() { 'a', 'e', 'i', 'o', 'u' };
            return inputString.ToLower().Count(c => vowels.Contains(c));
        }
    }
}

We again use the list of vowels just like in the first solution. Then we use the Count() LINQ function to count the vowels. We do that by providing a lambda function to go through each character in the string and see if the vowel list contains the given character.

The unit tests will pass just like before.

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

2 Responses to Find the vowels in a string with C# .NET

  1. Rohit says:

    Which is the best approach out of three ?

    • Andras Nemes says:

      If this were a real assignment in commercial software I would certainly go for the LINQ solution, or maybe the Regex one. The iterator-based solution is too low-level, but still good to keep in mind. Your interviewer might ask you not use LINQ at all, only “base-bones” language constructs.

Leave a comment

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.