This problem may come up during an interview, and it’s a bit of fun. How do we determine if two strings are anagrams?
If you’re practicing for an interview, write your solution in a text editor rather than an IDE. For syntax coloring, Visual Studio Code without IntelliSense works well with support for many languages. I’ve provided my solution in C# (csharp) and Java followed by Objective-C (ObjC) and Swift at the bottom.
By definition, an anagram is a word or phrase formed from another word or phrase by rearranging the letters. Spaces and punctuation don’t count, just the letters ignoring case. Here are a few samples:
“Tom Marvolo Riddle” <-> “I am Lord Voldemort!”
“Dave Barry” <-> “Ray Adverb”
“debit card” <-> “bad credit”
“astronomer” <-> “Moon starer”
“School master” <-> “the classroom”
Since we must use all of the letters we can conclude that ignoring spaces and punctuation, the two strings must be the same length. Also, the same phrase is not an anagram of itself.
Notice that if we sort the letters of a phrase and its anagram we get identical strings.
Let’s assume gibberish is acceptable. We want to allow proper names, and a person could create a secret password from an actual phrase. With this assumption we won’t need to look up words in a dictionary, and we can test secret passwords and phrases.
Some test strings that should fail:
“banana” and “bananas” are not the same length
“bananab” and “abanana” are subsets but not anagrams
“Tom Riddle” and “I’m Lord Voldemort?”
The first step is to check our arguments for correctness and if we need bother testing. We’ll remove spaces and punctuation before testing if strings are the same, and we’ll force all the characters to lowercase since lettercase doesn’t matter. Naturally, you may wish to use console arguments, ask for user input, or a load a list to test anagrams.
Note: if asked instead to find if two strings are permutations of each other, it’s even easier: skip the character removal.
Note the use of System.Linq.Enumerable.SequenceEqual to compare arrays since in C# Array.Equals compares instances, not contents. If testing this code in Visual Studio 2013, remember to use Start Without Debugging to see the console window. In Java you can use System.out.println instead of System.Console.WriteLine, and see String.replaceAll for regular expression replacement.
What if we wanted to allow “Ray.adverb” as a single string counting the period? Of course, “ray-adverb” should still count as two words and ignore the hypen. Instead of stripping all punctuation, we’d need to consider word boundaries. Let’s try this in a Swift Playground since Playgrounds make it easy to try things out and see the changes.