patterncsharpMinor
Pairing anagrams in a string list
Viewed 0 times
pairingliststringanagrams
Problem
The task was to check for pairs of anagrams in a string list.
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 anagarms = new List();
anagarms.Add("Gilad");
anagarms.Add("dilaG");
anagarms.Add("bat");
anagarms.Add("but");
anagarms.Add("utb");
pairs = PairAnagrams(anagarms);
pairs = PairAnagramsHash(anagarms);
}
Dictionary PairAnagrams(List wordsList)
{
Dictionary dictionary = new Dictionary();
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(sortedWord2);
int i;
for (i = 0; i PairAnagramsHash(List wordList)
{
Dictionary dictionary = new Dictionary();
foreach (var item in wordList)
{
foreach (var item2 in wordList)
{
- 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 anagarms = new List();
anagarms.Add("Gilad");
anagarms.Add("dilaG");
anagarms.Add("bat");
anagarms.Add("but");
anagarms.Add("utb");
pairs = PairAnagrams(anagarms);
pairs = PairAnagramsHash(anagarms);
}
Dictionary PairAnagrams(List wordsList)
{
Dictionary dictionary = new Dictionary();
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(sortedWord2);
int i;
for (i = 0; i PairAnagramsHash(List wordList)
{
Dictionary dictionary = new Dictionary();
foreach (var item in wordList)
{
foreach (var item2 in wordList)
{
Solution
Algorithm of
You are calling
inside the inner loop, but
One time you are using
This
can be replaced by
By using
By using the
This reduces the code to
Constructor
The constructor of an object should be used only for constructing the object. You are misusing it to start the action.
Naming
General
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(sortedWord2); Be consistent in your style. This
for (i = 0; i < 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 PairAnagrams(List words)
{
Dictionary pairedAnagrams = new Dictionary();
foreach (var word in words)
{
if (pairedAnagrams.ContainsValue(word))
{
continue;
}
var sortedWord1 = word.OrderBy(c => c);
int wordLength = word.Length;
foreach (var word2 in words.Where(w => w.Length == wordLength && !word.Equals(w)))
{
if (sortedWord1.SequenceEqual(word2.OrderBy(c => 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.
anagarmsvsanagrams
- parameters should't be pre/post fixed by their types.
List wordsList->List words
General
- no need for
using System.Security.Cryptography
Code Snippets
var sortedWord1 = item.ToArray();
Array.Sort(sortedWord1);for (i = 0; i < sortedWord2.Length; i++)
{
if (sortedWord2[i] != sortedWord1[i])
{
break;
}
}
if (i == sortedWord1.Length)
{
dictionary.Add(item, item2);
}if (sortedWord1.SequenceEqual(sortedWord2))
{
dictionary.Add(item, item2);
}Dictionary<string, string> PairAnagrams(List<string> words)
{
Dictionary<string, string> pairedAnagrams = new Dictionary<string, string>();
foreach (var word in words)
{
if (pairedAnagrams.ContainsValue(word))
{
continue;
}
var sortedWord1 = word.OrderBy(c => c);
int wordLength = word.Length;
foreach (var word2 in words.Where(w => w.Length == wordLength && !word.Equals(w)))
{
if (sortedWord1.SequenceEqual(word2.OrderBy(c => c)))
{
pairedAnagrams.Add(word, word2);
}
}
}
return pairedAnagrams;
}Context
StackExchange Code Review Q#73626, answer score: 3
Revisions (0)
No revisions yet.