Check whether two strings are anagrams

Viewed 181

What is the most straightforward way to check whether two strings are anagrams? i.e. they share the same letters as well as number of occurrences of each these letters (and possibly other characters).

Something like this:

s1 = "elbow"
s2 = "below"

is_anagram(s1, s2)
# [1] TRUE
3 Answers

One way to do it is:

s1 = "elbow"
s2 = "below"

is_anagram <- function(s1, s2){
  s1_sorted <- sort(strsplit(s1, "")[[1]])
  s2_sorted <- sort(strsplit(s2, "")[[1]])
  identical(s1_sorted, s2_sorted)
}

#> is_anagram(s1, s2)
#> [1] TRUE

You can try the code below

> do.call(identical,Map(function(x) sort(utf8ToInt(x)), list(s1, s2)))
[1] TRUE

If you want to generalize the case to more than two strings, e.g.,

s1 <- "elbow"
s2 <- "below"
s3 <- "owlbe"

then we can try

> lst <- list(s1, s2, s3)

> all(apply(table(stack(Map(utf8ToInt, setNames(lst, seq_along(lst))))), 1, var) == 0)
[1] TRUE

or

> lst <- list(s1, s2, s3)

> m <- as.data.frame.matrix(table(stack(Map(utf8ToInt, setNames(lst, seq_along(lst))))))

> identical(do.call(pmin, m), do.call(pmax, m))
[1] TRUE

A simple way to achieve that:

library(tidyverse)

s1 = "elbow"
s2 = "below"

is_anagram <- function(s1, s2){
  identical(str_split(s1, "") %>% table, str_split(s2, "") %>% table)
}

is_anagram(s1, s2)

#> [1] TRUE
Related