Pairing anagrams in a string list The task was to check for pairs of anagrams in a string list.


I first sorted all the words. and looped over the letters.
The interview continues with a follow-up, to do the same with limited memory.
I tried to implement a Hash function.


The dictionary return value is only for my convince in order to see all the pairs. I could just print it into the console instead.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class ReverseString
    {
        public ReverseString()
        {                 
            List&lt;string&gt; anagarms = new List&lt;string&gt;();
            anagarms.Add("Gilad");
            anagarms.Add("dilaG");
            anagarms.Add("bat");
            anagarms.Add("but");
            anagarms.Add("utb");
            pairs = PairAnagrams(anagarms);
            pairs = PairAnagramsHash(anagarms);
        }

        Dictionary&lt;string, string&gt; PairAnagrams(List&lt;string&gt; wordsList)
        {
            Dictionary&lt;string, string&gt; dictionary = new Dictionary&lt;string, string&gt;();
            foreach(var item in wordsList)
            {
                if (dictionary.ContainsValue(item))
                {
                    continue;
                }
                foreach(var item2 in wordsList)
                {
                    if(item.Length != item2.Length || item.Equals(item2))
                    {
                        continue;
                    }

                    var sortedWord1 = item.ToArray();
                    Array.Sort(sortedWord1);
                    var sortedWord2 = item2.ToArray();
                    Array.Sort&lt;char&gt;(sortedWord2);
                    int i;
                    for (i = 0; i &lt; sortedWord2.Length; i++)
                    {
                        if (sortedWord2[i] != sortedWord1[i])
                        {
                            break;
                        }
                    }
                    if(i == sortedWord1.Length)
                    {
                        dictionary.Add(item, item2);
                    }
                }
            }
            return dictionary;
        }

        Dictionary&lt;string, string&gt; PairAnagramsHash(List&lt;string&gt; wordList)
        {
            Dictionary&lt;string, string&gt; dictionary = new Dictionary&lt;string, string&gt;();

            foreach (var item in wordList)
            {
                foreach (var item2 in wordList)
                {
                    if (item.Equals(item2) || dictionary.ContainsKey(item2))
                    {
                        continue;
                    }
                    if (HashFunction(item) == HashFunction(item2))
                    {
                        dictionary.Add(item, item2);
                    }
                }
            }
            return dictionary;
        }

        public int HashFunction(string word)
        {
              int result = 0;
              var charArray = word.ToArray();
              for (int i = 0; i &lt; word.Length; i++)
              {
                  result += charArray[i] * 37;
              }
              return result;
        }
    }
}
Algorithm of PairAnagrams()  

You are calling 


var sortedWord1 = item.ToArray();
Array.Sort(sortedWord1);



inside the inner loop, but item won't change there.  

One time you are using Array.Sort(sortedWord1); and two lines below Array.Sort&lt;char&gt;(sortedWord2); Be consistent in your style.  

This  


for (i = 0; i &lt; sortedWord2.Length; i++)
{
    if (sortedWord2[i] != sortedWord1[i])
    {
        break;
    }
}
if (i == sortedWord1.Length)
{
    dictionary.Add(item, item2);
}  



can be replaced by  

if (sortedWord1.SequenceEqual(sortedWord2))
{
    dictionary.Add(item, item2);
}  


By using .Where() on the wordList at the for each you can omit the check for length and equal.  

By using the .OrderBy() on the chars of the words, there won't be a need to call .ToArray() and Array.Sort().

This reduces the code to  

Dictionary&lt;string, string&gt; PairAnagrams(List&lt;string&gt; words)
{
    Dictionary&lt;string, string&gt; pairedAnagrams = new Dictionary&lt;string, string&gt;();
    foreach (var word in words)
    {
        if (pairedAnagrams.ContainsValue(word))
        {
            continue;
        }

        var sortedWord1 = word.OrderBy(c =&gt; c);
        int wordLength = word.Length;
        foreach (var word2 in words.Where(w =&gt; w.Length == wordLength &amp;&amp; !word.Equals(w)))
        {
            if (sortedWord1.SequenceEqual(word2.OrderBy(c =&gt; c)))
            {
                pairedAnagrams.Add(word, word2);
            }
        }
    }
    return pairedAnagrams;
}


Constructor  

The constructor of an object should be used only for constructing the object. You are misusing it to start the action.  

Naming  


variable names should be correctly spelled. anagarms vs anagrams  
parameters should't be pre/post fixed by their types. List&lt;string&gt; wordsList-> List&lt;string&gt; words  


General  


no need for using System.Security.Cryptography