patterncppMinor
HackerRank Anagram
Viewed 0 times
hackerrankanagramstackoverflow
Problem
I was (yet again!) inspired by a previous question to post some code to solve the same problem. In this case, the problem in question is the Anagram challenge on HackerRank. The basic idea is that you're given some number of lines of input. Each line of input represents two strings (with no delimiter between them), each being as close to half the length of the line as possible (and if it's odd, the first is the shorter of the two, not that it matters much).
You're to find how many characters in the first need to be changed to make it an anagram of the second (or -1 if they can't be made anagrams of each other). For each line of input (other than the number specifying the length) you're to produce one line of output containing that number).
My code for this was as follows:
You're to find how many characters in the first need to be changed to make it an anagram of the second (or -1 if they can't be made anagrams of each other). For each line of input (other than the number specifying the length) you're to produce one line of output containing that number).
My code for this was as follows:
#include
#include
#include
#include
#include
#include
int anagram_check(std::string &line) {
// If the length is odd, they can't be anagrams
if (line.length() % 2 != 0)
return -1;
size_t len = line.length() / 2;
auto mid = line.begin() + len;
// sort each half
std::sort(line.begin(), mid);
std::sort(mid, line.end());
// find number of characters that are different:
std::string diffs;
std::set_difference(line.begin(), mid, mid, line.end(), std::back_inserter(diffs));
return diffs.size();
}
int main() {
int num;
// Read number of test cases:
std::cin >> num;
// Clear remainder of line from input buffer:
std::string ignore;
std::getline(std::cin, ignore);
std::string line;
for (int i = 0; i < num; i++) {
std::getline(std::cin, line);
std::cout << anagram_check(line) << "\n";
}
}Solution
Frankly, your solution is simple, short and elegant enough. I don't think there is much to add, but let's try a few tips an ideas:
-
I sometimes advise people to arrange headers from a same library in alphabetical order; it generally helps to avoid including headers twice like you did with `
Of course it only works well with a small alphabet (you can cache the prime numbers if the size of the alphabet is small) and becomes impractical for big words unless you use infinite integers, but at least it's funny :p
-
I sometimes advise people to arrange headers from a same library in alphabetical order; it generally helps to avoid including headers twice like you did with `
. If you have a better semantic ordering for your headers, that's fine, but if you don't, alphabetical order helps to quickly find a header and avoid duplicate includes.
-
It doesn't really matter, but using the global std::begin and std::end is slightly better in the event that you someday want to use a generic type instead of std::string.
-
You only need the size of the set difference, not the set difference itself. If you wanted to, you could write a fancy iterator that only counts the number of times it is incremented and ignores what it is assigned to avoid copying things. That could be somewhat fun.
If you want a fun solution: associate every letter of the first word to the \$n\$th prime number (a to \$1\$, b to \$2\$, etc...) and multiply together every prime number correspond to the letters of the first word, let's call this result the product. Now, for every letter of the second word, associate it to its corresponding prime number p and compute std::div(product, p). If the remainder is \$0\$, it means that the letter was in the first word, assign the result of the division to product`; otherwise, it means that the letter wasn't in the first word and you can increment the difference counter.Of course it only works well with a small alphabet (you can cache the prime numbers if the size of the alphabet is small) and becomes impractical for big words unless you use infinite integers, but at least it's funny :p
Context
StackExchange Code Review Q#116354, answer score: 4
Revisions (0)
No revisions yet.