Reputation: 1328
The string or word can be of any length.
Eg "William Shakespeare" = "I am a weakish speller" both are anagrams
E.g. "Madam Curie" = "Radium came"
Upvotes: 2
Views: 1818
Reputation: 2807
don't waste time sorting the characters in the string. Just sequentially count frequencies of them, and compare. An anagram, by definition, would cancel out each other's buckets perfectly.
Upvotes: 0
Reputation: 1315
Sort characters in strings and compare irrespective of case.
str1="$1"
str2="$2"
sorted1=$(echo $str1 | grep -o . | sort | tr -d "\n")
sorted2=$(echo $str2 | grep -o . | sort | tr -d "\n")
if [[ $(typeset -l $sorted1) == $(typeset -l $sorted2) ]]
then
echo "Strings are anagrams"
else
echo "Strings are not anagrams"
fi
Upvotes: 0
Reputation: 67
#!/bin/bash
#set -x
i=0
for letter in {A..Z}
do
alphabet[$i]="$letter"
((i++))
done
i=0
for digits in {0..25}
do
array[$i]=0
((i++))
done
read -p "Enter first word: " word1
read -p "Enter second word: " word2
while read -n 1 letter
do
if [ -z "$letter" ]
then continue
fi
for b in "${!alphabet[@]}"
do
if [ "$letter" = "${alphabet[$b]}" ]
then
((array[$b]+=1))
break
fi
done
done < <(echo "${word1^^}")
while read -n 1 letter
do
if [ -z "$letter" ]
then continue
fi
for b in "${!alphabet[@]}"
do
if [ "$letter" = "${alphabet[$b]}" ]
then
((array[$b]-=1))
break
fi
done
done < <(echo "${word2^^}")
echo -n "Words are "
for element in "${array[@]}"
do
if [ "$element" -ne 0 ]
then echo -n "not "
fi
done
echo "anagrams"
echo
exit
And in functions
#!/bin/bash
set -x
i=0
for letter in {A..Z}
do
alphabet[$i]="$letter"
((i++))
done
read_word(){
local array=()
local i=0
for digits in {0..25}
do
array[$i]=0
((i++))
done
local sentence="$1"
while read -n 1 letter
do
if [ -z "$letter" ]
then continue
fi
for b in "${!alphabet[@]}"
do
if [ "$letter" = "${alphabet[$b]}" ]
then
((array[$b]+=1))
break
fi
done
done < <(echo "${sentence^^}")
echo "${array[@]}"
}
equal_array(){
if [ "$1" = "$2" ]
then echo "anagrams"
else echo " not anagrams"
fi
}
read -p "Enter first word: " word1
read -p "Enter second word: " word2
word1=($(read_word "$word1"))
word2=($(read_word "$word2"))
equal_array "${word1[*]}" "${word2[*]}"
exit
Upvotes: 0
Reputation: 195029
an awk solution looks not so compact like others, but slightly different:
awk -v s1="William Shakespeare" -v s2="I am a weakish speller" '
function chkTxt(s) {
split(tolower(s), arr, //)
asort(arr)
result=""
for(i=1;i<=length(arr);i++)
result = result""arr[i]
return result
}
BEGIN{
x=gsub(/[[:blank:]]/,"",s1)
y=gsub(/[[:blank:]]/,"",s2)
if (x+y==0 || (x&&y)) {
print chkTxt(s1)==chkTxt(s2)? "True":"False"
exit
}
print "False"
}'
here you pass the two string variable to s1
and s2
.
Note For space/blank checking, I noticed that your example doesn't restrict the count of the spaces, however, it seems that if there were spaces, two strings must have at least one spaces. Like foo bar
and f o o ba r
are anagrams. However foobar
and barf o o
are not.
The above codes do the check.
Upvotes: 0
Reputation: 92854
Easy with Python:
anagram.py script:
import sys
s1 = sys.argv[1]
s2 = sys.argv[2]
fmt = '"{:s}" and "{:s}" are{:s} anargams'
if sorted(s1.lower().translate(None,' \n\r\t')) == sorted(s2.lower().translate(None,' \n\r\t')):
print(fmt.format(s1, s2, ''))
else:
print(fmt.format(s1, s2, ' NOT'))
Usage:
python anagrams.py "William Shakespeare" "I am a weakish speller"
The output:
"William Shakespeare" and "I am a weakish speller" are anargams
python anagrams.py "William Shakespeare" "William Hopkins"
The output:
"William Shakespeare" and "William Hopkins" are NOT anargams
Upvotes: 1
Reputation: 784918
This may work for you:
# function to cleanup a given argument by doing this:
# 1. Remove all alphanumerics
# 2. Convert to all lowercasing all characters
# 3. Sorting all characters
# 4. Stripping all newlines
prep() {
fold -w1 <<< "${1//[^[:alnum:]]/}" | tr '[:upper:]' '[:lower:]' | sort | tr -d '\n'
}
# function to check if given 2 arguments are anagrams
isAnagram() {
a=$(prep "$1")
b=$(prep "$2")
[[ $a = $b ]] && echo "yes" || echo "no";
}
To call them use:
isAnagram "William Shakespeare" "I am a weakish speller"
yes
isAnagram "Madam Curie" "Radium came"
yes
isAnagram "cat" "act"
yes
isAnagram "cat" "cot"
no
Upvotes: 4