Given a string, we can "shift" each of its letter to its successive letter, for example: "abc"
-> "bcd"
. We can keep "shifting" which forms the sequence:
"abc" -> "bcd" -> ... -> "xyz"
Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence.
For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"]
,
Return:
[
["abc","bcd","xyz"],
["az","ba"],
["acef"],
["a","z"]
]
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector< vector<string> > groupStrings(vector<string>& strings) {
unordered_map<string, vector<string> > map;
vector< vector< string> > res;
for(auto str : strings) {
string tmp = str;
for(int i = tmp.size() - 1; i >= 0; --i) {
tmp[i] = ('a' + (tmp[i] - tmp[0] + 26) % 26); // since it is group shifted.
}
map[tmp].push_back(str);
}
for(auto val : map) {
sort(val.second.begin(), val.second.end());
res.push_back(val.second);
}
return res;
}
int main(void) {
vector<string> str{"abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"};
vector< vector<string> > res = groupStrings(str);
for(int i = 0; i < res.size(); ++i) {
for(int j = 0; j < res[i].size(); ++j) {
cout << res[i][j] << " ";
}
cout << endl;
}
}