2

It'd be really to implement in Java, since you could use the Comparator and the built in methods to sort character arrays and compare strings like this:

public class AnagramComparator implements Comparator<String> {
 public String sortChars(String s) {
   char[] content = s.toCharArray();
   Arrays.sort(content);
   return new String(content);
 }

public int compare(String s1, String s2) {
   return sortChars(s1).compareTo(sortChars(s2));
 }
}

But I'm wondering how would one go about implementing this in C++? Coding the C++ equivalent of the built-in methods used in the above Java code is definitely one option. Is there any other intelligent way?

GrowinMan
  • 4,891
  • 12
  • 41
  • 58

2 Answers2

5

The obvious and also the best way is quite similar to the one you chose in Java: implement a custom comparer.

In C++, that’s a specialisation of a less-than predicate:

struct less_than_sorted_anagram {
    bool operator ()(std::string a, std::string b) {
        std::sort(a.begin(), a.end());
        std::sort(b.begin(), b.end());
        return a < b;
    }
};

And call it like this:

std::vector<std::string> range;
// …
std::sort(range.begin(), range.end(), less_than_sorted_anagram());

But (just like your Java code) this is quite inefficient since the sorted anagrams have to be computed repeatedly. It would be much more efficient to only compute them once (on first use, say) and cache them.

You could for instance maintain this cache inside the less_than_sorted_anagram predicate as a std::map<std::string, std::string> (or a similar dictionary mapping strings to strings).

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

A two-level approach:

Sort the the string s into a sorted string t, and add an entry to a map<string, vector<string> as m[t].push_back(s);. Then each entry of the map is a vector of mutually anagrammatic strings.

You could implement the same logic in a single, flat multimap, but that would be far more expensive (since you'd have to sort the string each time); or you could make a comparator that lexicographically compares the sorted string first and the actual string second, but again that's very expensive.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084