Anagrams Checker - Three JavaScript Solutions

Anagrams Checker - Three JavaScript Solutions

Anagrams are words that have the same characters in the same quantity. We will consider 3 JavaScript solutions in this article.

Originally published by Sarah Chima at dev.to

I started a series on JavaScript solutions to common algorithms and javascript problems. In case you missed the first one, here's a link to it. Earlier this week, I wrote an article on the Big O notation. If you are not familiar with it, you might want to read it as some concepts are used in this article. Let's go straight to the problem statement.

Finding Anagrams - the problem

Anagrams are words that have the same characters in the same quantity. This means that two strings are anagrams if we can rearrange one to get the other.

Here are some examples of words that are anagrams.

  1. “listen” and “silent”
  2. “rail safety” and “fairy tales”
  3. “dormitory” and “dirty room”
  4. “the eyes” and “they see”

To solve this problem, we will assume the following:

  1. That we ignore extra characters like “!”, “@”, etc. and whitespaces.
  2. We only want to work with lowercase characters.

Let us look at some solutions to this problem. Then we'll compare each of them based on their time complexity.

Solution 1 - Create a character map of both strings and compare maps

A character map in this context is a map or object that contains each unique character in the string. It stores the character as a key and the number of times it occurs in that string as the value.

function anagrams(stringA, stringB) {
        /*First, we remove any non-alphabet character using regex and convert
        convert the strings to lowercase. */
        stringA = stringA.replace(/[^\w]/g, "").toLowerCase()
        stringB = stringB.replace(/[^\w]/g, "").toLowerCase()

    //Get the character map of both strings
    const charMapA = getCharMap(stringA)
    const charMapB = getCharMap(stringB)

    /* Next, we loop through each character in the charMapA, 
    and check if it exists in charMapB and has the same value as
    in charMapA. If it does not, return false */
    for (let char in charMapA) {
        if (charMapA[char] !== charMapB[char]) {
            return false
        }
    }

    return true
}

function getCharMap(string) {
    // We define an empty object that will hold the key - value pairs.
    let charMap = {}

    /*We loop through each character in the string. if the character 
    already exists in the map, increase the value, otherwise add it 
    to the map with a value of 1 */
    for (let char of string) {
        charMap[char] = charMap[char] + 1 || 1
    }
    return charMap
}

The runtime complexity of a for loop is linear i.e O(n). In this case, there are 3 consecutive forloops which are not nested. Ignoring constants and other factors, the time complexity is approximately linear i.e. O(n).

2. Sort Strings and check if they are the same

This is a shorter and neater way of checking if two strings are anagrams.

In this case, we convert the string to an array, use the Array.sort() 

method to sort it and convert it back to a string. Then we compare both strings and check if they are the same.

    function anagrams(stringA, stringB) {
        /*First, we remove any non-alphabet character using regex and convert
convert the strings to lowercase. */ stringA = stringA.replace(/[^\w]/g, '').toLowerCase() stringB = stringB.replace(/[^\w]/g, '').toLowerCase()

    return sortString(stringA) === sortString(stringB)
}

/*This function sorts the strings*/ 
function sortString(string) {
    return string.split('').sort().join('');
}

Array.sort uses merge sort so its time complexity is O(nlogn).

3. Using Array.splice()

This is yet another solution. In this case, we convert string B to an array, loop through each character in string A and check if it exists in an array of string B, arrB. If it exists, we use the Splice method to remove it from the array. We do this so that characters that occur more than once in arrB are not checked twice.

    function anagrams(stringA, stringB) {
        /*First, we remove any non-alphabet character using regex and convert
convert the strings to lowercase. */ stringA = stringA.replace(/[^\w]/g, '').toLowerCase() stringB = stringB.replace(/[^\w]/g, '').toLowerCase()

    /*Next, we check if the lengths of the strings are equal. 
    If they are anagrams, they will have the same length. */
    if (stringA.length !== stringB.length) {
        return false
    }

    let arrB = stringB.split("")

    for (let char of stringA ){ 
        if (!arrB.includes(char)) {
            return false
            break;
        } else {
            arrB.splice(arrB.indexOf(char), 1)
        }
    }

    return true

}

So let's consider the time complexity of this solution. In this case, there are three loops that run. The for loop, the includes loop and the splice loop. Since the splice loop and the includes are not nested, the time complexity tends to O(n2 ).

Conclusion

We have seen the solutions and their approximate time complexities. Comparing their time complexities, the first solution seems to have better performance. It has an approximate time complexity of O(n). The second solution, however, is more concise. So you can choose any solution depending on what is more important to you.

Got any question or addition? Please leave a comment.

Thank you for reading.

Originally published by Sarah Chima at dev.to

===========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Svelte.js - The Complete Guide

☞ The Complete JavaScript Course 2019: Build Real Projects!

☞ Become a JavaScript developer - Learn (React, Node,Angular)

☞ JavaScript: Understanding the Weird Parts

☞ JavaScript: Coding Challenges Bootcamp - 2019

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch

javascript web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.