<p>Given an array of strings <code>strs</code>, group the <span data-keyword="anagram">anagrams</span> together. You can return the answer in <strong>any order</strong>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;eat&quot;,&quot;tea&quot;,&quot;tan&quot;,&quot;ate&quot;,&quot;nat&quot;,&quot;bat&quot;]</span></p>

<p><strong>Output:</strong> <span class="example-io">[[&quot;bat&quot;],[&quot;nat&quot;,&quot;tan&quot;],[&quot;ate&quot;,&quot;eat&quot;,&quot;tea&quot;]]</span></p>

<p><strong>Explanation:</strong></p>

<ul>
	<li>There is no string in strs that can be rearranged to form <code>&quot;bat&quot;</code>.</li>
	<li>The strings <code>&quot;nat&quot;</code> and <code>&quot;tan&quot;</code> are anagrams as they can be rearranged to form each other.</li>
	<li>The strings <code>&quot;ate&quot;</code>, <code>&quot;eat&quot;</code>, and <code>&quot;tea&quot;</code> are anagrams as they can be rearranged to form each other.</li>
</ul>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;&quot;]</span></p>

<p><strong>Output:</strong> <span class="example-io">[[&quot;&quot;]]</span></p>
</div>

<p><strong class="example">Example 3:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;a&quot;]</span></p>

<p><strong>Output:</strong> <span class="example-io">[[&quot;a&quot;]]</span></p>
</div>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= strs.length &lt;= 10<sup>4</sup></code></li>
	<li><code>0 &lt;= strs[i].length &lt;= 100</code></li>
	<li><code>strs[i]</code> consists of lowercase English letters.</li>
</ul>

template <std::size_t N>
struct character_frequencies {
  character_frequencies(const std::string& string) {
    for (const char character : string) {
      ++frequencies[character - 'a'];
    }
  }

  char frequencies[N] = {0};
};

template <std::size_t N>
bool operator==(const character_frequencies<N>& lhs, const character_frequencies<N>& rhs) {
  for (std::size_t index{0}; index < N; ++index) {
    if (lhs.frequencies[index] != rhs.frequencies[index]) {
      return false;
    }
  }
  return true;
}
  
class Solution {
public:
  std::vector<std::vector<std::string>> groupAnagrams(const std::vector<std::string>& strings) {
    std::vector<std::vector<std::string>> anagrams;
  
    for (const std::string& string : strings) {
      bool found{false};
  
      const character_frequencies<26> frequencies_string{string};
  
      for (auto& group : anagrams) {
        const character_frequencies<26> frequencies_group{group.front()};
        if (frequencies_string == frequencies_group) {
          group.push_back(string);
          found = true;
          break;
        }
      }
  
      if (!found) {
        anagrams.push_back({string});
      }
    }
  
    return anagrams;
  }

};
15115