Anagram in C#

One string is an anagram of another if it uses the same characters in the same number!

The goal is to check whether two strings — Anagram and Nag A Ram! — are anagrams of each other. Here, we only want to consider characters and ignore spaces or punctuations. Also, we want to consider uppercase letters to be the same as a lowercase character.

Character Dictionary

We are going to write a helper function to build a character dictionary for a given string. we replace any non-word characters with nothing using Regex.Replace() static method. The Regex class is defined in the System.Text.RegularExpressions namespace. An overload of the Regex.Replace() substitutes the matched pattern with the pattern that is defined by the replacement parameter. After the clean-up logic, we convert the entire string to lowercase.

Then we iterate over the string characters. If the dictionary has not yet contained the character, we create an entry with character as the key and the value of one. Otherwise, we increment the value for that key. For implementation, we use the TryGetValue() method. You can read more about TryGetValue() method here.

using System.Collections.Generic;
using System.Text.RegularExpressions;

private static Dictionary<char, int> BuildCharDic(string str)
{
    var charDic = new Dictionary<char, int>();

    var refinedStr = Regex.Replace(str, @"\W", "").ToLower();

    foreach (var character in refinedStr)
    {
        if (!charDic.TryGetValue(character, out var i))
        {
            charDic.Add(character, 1);
        }
        else
        {
            charDic[character] = ++i;
        }
    }

    return charDic;
}

In the main method, we check whether the two strings are the same. Otherwise, we will use the helper method to produce a character dictionary for both strings. Then, we will look at the number of keys of both these character dictionaries and check to see if they are identical in the count. If not, then we must know that we do not have an anagram because they have a different number of characters. In other words, one character dictionary has an extra character that the other one does not. Therefore, if that’s the case, we will return false from this method.

public static bool Anagrams(string strA, string strB)
{
    if (strA.Equals(strB))
    {
        return true;
    }

    var strACharDic = BuildCharDic(strA);
    var strBCharDic = BuildCharDic(strB);

    if (strACharDic.Keys.Count != strBCharDic.Keys.Count)
    {
        return false;
    }

    foreach (var character in strACharDic.Keys)
    {
        if (!strBCharDic.ContainsKey(character) ||
            strACharDic[character] != strBCharDic[character])
        {
            return false;
        }
    }

    return true;
}

If they have the same number of keys, we want to proceed with the dictionary checking process, in which we will iterate over keys property of the first character dictionary and look at every key/value pair of it and compare it to the other character dictionary key/value pairs. If we succeed in these checks, that means that they must be anagrams, and so in that case the method will return true.

Linq Operators

The next solution for handling anagrams is using LINQ Operators. We are going to take the two inputs, clean up both strings by removing any spaces or punctuation, and lowercase both strings using the RefineString method. Then we are going to sort both strings using the LINQ OrderBy operator.

using System.Linq;
using System.Text.RegularExpressions;

private static string RefineString(string str)
{
    return Regex.Replace(str, @"\W", "").ToLower();
}

public static bool Anagrams(string strA, string strB)
{
    return RefineString(strA)
        .OrderBy(a => a)
        .SequenceEqual(
            RefineString(strB)
                .OrderBy(b => b)
            );
}

When sorting both strings, no matter what characters we have inside, they will end up in the exact same order. If the two sorted strings are then completely identical, then we can say that we have an anagram. We used the SequenceEqual() method of LINQ for comparing the characters of two strings.

You can download the source code on Github.