I need to compare 2
strings and see if the number of every character each of them contain is the same.
Requirement:
Without using any packages or imports
My idea:
I want to check if a char from charsA
exists within charsB
. And if it does, I'll remove it from charsB
.
And if the length of charsB
is 0
by the end of the for
loop, then I know it is an anagram
Issue:
It might end up deleting each character that matches a particular character more than once.
For example, if input is "oellh"
and "heloo"
(result should be false
):
- checks for
o
: newcharsB
:"hel"
- checks for
e
: newcharsB
:"hl"
- checks for
l
: newcharsB
:"h"
- checks for
l
: newcharsB
:"h"
- checks for
h
: newcharsB
:""
My code:
static boolean isAnagram(String a, String b) {
boolean isAnagram;
//case 2:
//if strings lengths dont match isAnagram is set to false
if(a.length() != b.length()){isAnagram = false;}
// will turn each string into an array or characters
String[] charsA = a.split("");
String[] charsB = b.split("");
for (int i = 0; i < a.length(); i ) {
// some code to compare the strings here.
}
return isAnagram;
}
Test cases
*Input:
"hello", "olhel" // case one
"helloq", "olhel" // case two
"helloq", "olheln" // case three
Output:
true // case one
false // case two
false // case three
CodePudding user response:
Generate a HashMap
of frequencies of symbols for both given strings.
Then compare the two maps. If they are equal, then the strings are anagrams.
public static boolean isAnagram(String a, String b) {
return getFrequencies(a).equals(getFrequencies(b));
}
public static Map<Integer, Long> getFrequencies(String str) {
return str.codePoints()
.boxed()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
}
main()
public static void main(String[] args) {
System.out.println(isAnagram("hello", "olhel"));
System.out.println(isAnagram("hello", "olhelq"));
}
Output:
true
false
Without using any packages or imports
There are different possibilities, the optimal choice would depend on the constraints on the strings received as an input.
If we expect that input will contain only letters of the English alphabet, then we could handle this case by populating two arrays of length 26
where each element corresponds to a frequency of a particular letter (as shown in the link provided by @Federico klez Culloca in the comments). To get the result, we can compare these arrays iterating over the indices and checking values at the same index are equal. This algorithm will run in a linear time O(n) (as well as map-based solution shown above).
In case if we can't expect that symbols in the given strings would be in a particular range, then we can extract arrays of characters from both strings, sort them and compare both array character by character. This algorithm will run in a linear-logarithmic time O(n * log n) because it requires sorting. And since we are not allowed to use imports (like Arrays
utility class) then we need to implement a linear-logarithmic sorting algorithm (like quicksort or merge-sort) manually.