#include <bits/stdc++.h>
using namespace std;
typedef vector<string>::size_type line_no;
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm;
shared_ptr<vector<string>> handlePunct(const string &s) {
shared_ptr<vector<string>> p =
make_shared<vector<string>>();
size_t first = 0, idx = 0;
while (idx != s.size()) {
if (ispunct(s[idx])) {
string word = s.substr(first, idx - first);
if (!word.empty())
p->push_back(word);
p->push_back(s.substr(idx, 1));
++idx;
first = idx;
}
else
++idx;
}
string trail = s.substr(first);
if (!trail.empty())
p->push_back(trail);
return p;
}
void func(ifstream &is) {
file = make_shared<vector<string>> ();
using std::getline;
string text;
while (getline(is, text)) {
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line >> word) {
auto p = handlePunct(word);
for (auto w : *p) {
auto &lines = wm[w];
if (!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
}
int main() {
ifstream in("in.txt");
func(in);
for (auto t : wm) {
string s = t.first;
auto p = t.second;
auto &tmp = *p;
cout << s << '\n';
for (auto k : tmp) cout << k << ' ';
cout << '\n';
}
return 0;
}