Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given two strings, is one an anagram of the other [closed]

Tags:

c#

I just started going through "Cracking the Coding Interview" and have the following solution for this problem:

public static bool isAnagram(String s, String t)
{
    if (s == "" || t == "") return false;
    else if (s.Length != t.Length) return false;

    int[] letters = new int[256];
    char[] s_array = s.ToCharArray();

    foreach(char c in s_array) 
    { 
        letters[c]++;  
    }

    for (int i = 0; i < t.Length; i++)
    {
        int c = t[i];
        if (--letters[c] < 0) 
        {
            return false;
        }
    }
    return true;
}

This is pretty much the verbatim solution from the book, only in C#, not Java, and with some additional nullchecks. I also solved the question using LINQ but wanted an additional solution that didn't involve sorting.

Can this approach be made a bit more elegant? The code works just fine, I just want to know if there is a more elegant or better solution out there. Thanks!!

like image 567
mynameisneo Avatar asked Apr 22 '13 07:04

mynameisneo


2 Answers

This code should work for you:

public static bool IsAnagram(string s1, string s2)
{
    if (string.IsNullOrEmpty(s1) || string.IsNullOrEmpty(s2))
        return false;
    if (s1.Length != s2.Length)
        return false;

    foreach (char c in s2)
    {
        int ix = s1.IndexOf(c);
        if (ix >= 0)
            s1 = s1.Remove(ix, 1);
        else
            return false;
    }

    return string.IsNullOrEmpty(s1);
}

Edit: Added non linq version.

You also may add some additional checks for null and empty values and move solution to StringBuilder to improve performance but intent of code is clear.

like image 68
Denys Denysenko Avatar answered Sep 26 '22 17:09

Denys Denysenko


As you have asked for more elegant solution, maybe this one fits your needs - more compacted, written as an extension method:

public static bool IsAnagram(this string s1, string s2)
{
    if (s1.Length == s2.Length)
    {
        var count = new int[1024];
        foreach (var c in s1)
        {
            ++count[c];
        }
        return s2.All(t => --count[c] >= 0);
    }
    return false;
}

var result = "mary".IsAnagram("army");
like image 29
jwaliszko Avatar answered Sep 26 '22 17:09

jwaliszko