patternMinor
Given a set of random strings, write a function that returns a set that groups all the anagrams together in objective-c
Viewed 0 times
randomgroupstheallanagramsfunctiontogetherwritethatreturns
Problem
I would like to get feedback on the solution and a question regarding Big O.
I am first converting each character in the string into the array and that would be O(n) then i am sorting the array O(n log n) and then I join back the array. Not sure if that is O(n). After i get the sorted string I would retrieve the NSArray from NSDictionary if it is there and either add the word to the array or create a new array and then set it back into the NSDictionary. I would those operations are O(1). The total runtime complexity is O(N log N) because of sort. Is that the correct breakdown.
```
void printAllAnagrams(NSArray *words)
{
NSMutableDictionary *anagramsDictionary = [[NSMutableDictionary alloc]init];
NSMutableArray *wordArray = [[NSMutableArray alloc]init];
for(NSString *word in words){
//Loop through each word
for(int i = 0;i < [word length]; i++){
//create a character array
[wordArray addObject:[NSString stringWithFormat:@"%c",[word characterAtIndex:i]]];
}
//sort character array
[wordArray sortUsingSelector:@selector(localizedCompare:)];
//convert character array back to string to use it as a key for in the dictionary
NSString *sortedString = [wordArray componentsJoinedByString:@""];
NSMutableArray *anagramStrings =[[anagramsDictionary objectForKey:sortedString] mutableCopy];
if(anagramStrings){
//if anagram(s) of the word is already in the dictionary then add this word to the array
//and store it back into the dictionary
[anagramStrings addObject:word];
[anagramsDictionary setObject:anagramStrings forKey:sortedString];
}else{
//create an array with current word and store it in the dictionary
//using the sorted characters string as the key
[anagramsDictionary setObject:@[word] forKey:sortedString];
}
[wordArray removeAllObjects];
}
NSLog(
I am first converting each character in the string into the array and that would be O(n) then i am sorting the array O(n log n) and then I join back the array. Not sure if that is O(n). After i get the sorted string I would retrieve the NSArray from NSDictionary if it is there and either add the word to the array or create a new array and then set it back into the NSDictionary. I would those operations are O(1). The total runtime complexity is O(N log N) because of sort. Is that the correct breakdown.
```
void printAllAnagrams(NSArray *words)
{
NSMutableDictionary *anagramsDictionary = [[NSMutableDictionary alloc]init];
NSMutableArray *wordArray = [[NSMutableArray alloc]init];
for(NSString *word in words){
//Loop through each word
for(int i = 0;i < [word length]; i++){
//create a character array
[wordArray addObject:[NSString stringWithFormat:@"%c",[word characterAtIndex:i]]];
}
//sort character array
[wordArray sortUsingSelector:@selector(localizedCompare:)];
//convert character array back to string to use it as a key for in the dictionary
NSString *sortedString = [wordArray componentsJoinedByString:@""];
NSMutableArray *anagramStrings =[[anagramsDictionary objectForKey:sortedString] mutableCopy];
if(anagramStrings){
//if anagram(s) of the word is already in the dictionary then add this word to the array
//and store it back into the dictionary
[anagramStrings addObject:word];
[anagramsDictionary setObject:anagramStrings forKey:sortedString];
}else{
//create an array with current word and store it in the dictionary
//using the sorted characters string as the key
[anagramsDictionary setObject:@[word] forKey:sortedString];
}
[wordArray removeAllObjects];
}
NSLog(
Solution
This would be a better way to do the final storage into the dictionary. Attempt to retrieve an existing list. If it does not exist, create it and add it to the dictionary. You can then unconditionally add the current
This avoids doing a copy every time, which in your original code is unnecessary in all cases but one.
Also worth noting is the last line here:
There is no need to put the mutable array back into the dictionary after getting a pointer to it, as you're doing. The array is not removed from the dictionary; your
word to the array.NSString *sortedString = [wordArray componentsJoinedByString:@""];
// Attempt to retrieve existing list
NSMutableArray * anagramStrings = [anagramsDictionary objectForKey:sortedString];
if( !anagramStrings ){
// If it does not exist, create it and put it into the dictionary
anagramStrings = [NSMutableArray array];
[anagramDictionary setObject:anagramStrings forKey:sortedString];
}
// Add to the list
[anagramStrings addObject:word];
[wordArray removeAllObjects];This avoids doing a copy every time, which in your original code is unnecessary in all cases but one.
Also worth noting is the last line here:
if(anagramStrings){
//if anagram(s) of the word is already in the dictionary then add this word to the array
//and store it back into the dictionary
[anagramStrings addObject:word];
[anagramsDictionary setObject:anagramStrings forKey:sortedString];
}There is no need to put the mutable array back into the dictionary after getting a pointer to it, as you're doing. The array is not removed from the dictionary; your
anagramStrings points to that exact same array.Code Snippets
NSString *sortedString = [wordArray componentsJoinedByString:@""];
// Attempt to retrieve existing list
NSMutableArray * anagramStrings = [anagramsDictionary objectForKey:sortedString];
if( !anagramStrings ){
// If it does not exist, create it and put it into the dictionary
anagramStrings = [NSMutableArray array];
[anagramDictionary setObject:anagramStrings forKey:sortedString];
}
// Add to the list
[anagramStrings addObject:word];
[wordArray removeAllObjects];if(anagramStrings){
//if anagram(s) of the word is already in the dictionary then add this word to the array
//and store it back into the dictionary
[anagramStrings addObject:word];
[anagramsDictionary setObject:anagramStrings forKey:sortedString];
}Context
StackExchange Code Review Q#127867, answer score: 3
Revisions (0)
No revisions yet.