C/C++

Помогите решить задачу c++

Помогите пожалуйста написать программу на C++
Однажды, разбирая старые книги на чердаке, школьник Вася нашёл англо-латинский словарь. Английский он к тому времени знал в совершенстве, и его мечтой было изучить латынь. Поэтому попавшийся словарь был как раз кстати.

К сожалению, для полноценного изучения языка недостаточно только одного словаря: кроме англо-латинского необходим латинско-английский. За неимением лучшего он решил сделать второй словарь из первого.

Как известно, словарь состоит из переводимых слов, к каждому из которых приводится несколько слов-переводов. Для каждого латинского слова, встречающегося где-либо в словаре, Вася предлагает найти все его переводы (то есть все английские слова, для которых наше латинское встречалось в его списке переводов), и считать их и только их переводами этого латинского слова.

Помогите Васе выполнить работу по созданию латинско-английского словаря из англо-латинского.

Входные данные

В первой строке содержится единственное целое число N — количество английских слов в словаре. Далее следует N описаний. Каждое описание содержится в отдельной строке, в которой записано сначала английское слово, затем отделённый пробелами дефис (символ номер 45), затем разделённые запятыми с пробелами переводы этого английского слова на латинский. Переводы отсортированы в лексикографическом порядке. Порядок следования английских слов в словаре также лексикографический.

Все слова состоят только из маленьких латинских букв, длина каждого слова не превосходит 15 символов. Общее количество слов на входе не превышает 100000.

Выходные данные

В первой строке программа должна вывести количество слов в соответствующем данному латинско-английском словаре. Со второй строки выведите сам словарь, в точности соблюдая формат входных данных. В частности, первым должен идти перевод лексикографически минимального латинского слова, далее — второго в этом порядке и т.д. Внутри перевода английские слова должны быть также отсортированы лексикографически.

Sample Input:

3
apple - malum, pomum, popula
fruit - baca, bacca, popum
punishment - malum, multa
Sample Output:

7
baca - fruit
bacca - fruit
malum - apple, punishment
multa - punishment
pomum - apple
popula - apple
popum - fruit

Примечание: Обратите внимание на следующую особенность чтения с потока ввода: при переходе от чтения по оператору >> к чтению по getline, в строке, из которой считали число n, остаётся символ новой строки. По этой причине, первая комнада getline , читающая по умолчанию до символа новой строки, считает пустую строку! Это можно исправить сделав "холостой" вызов функции getline перед циклом чтения строк, но по смыслу тут лучше всего подойдёт команда

cin >> ws;

или вместе с прочтением числа n:

cin >> n >> ws;

ws (whitespaces) - это функция модификатор потока ввода, удаляющая из него все разделительные символы, до первого появления символа отличного от разделительного!

Иногда ещё используют метод ignore,

cin.ignore()

удаляющий один символ из потока ввода. У этого метода есть два необязательных аргумента, по умолчанию удалится ровно одни символ неважно какой. Можно задать нашу цель более наглядно и явно (удалить один символ новой строки)

cin.ignore(1, '\n')

Если, как в нашем случае, речь идёт об удалении из потока ввода именно разделительных символов, то предпочтительнее ws, потому что он справляется с ситуациями когда в потоке ввода остаётся несколько разделительных символов и нам точно неизвестно какие это символы и сколько их.
Можно сделать так:
 #include 
#include
#include
#include
#include
#include

using namespace std;

const char* whitespaces = " \t\n\r\f\v";

void trim(string &s) {
s.erase(s.find_last_not_of(whitespaces) + 1);
s.erase(0, s.find_first_not_of(whitespaces));
}

vector split(const string &s, const char *sep) {
char* cstr = const_cast(s.c_str());
char *tok = strtok(cstr, sep);
vector result;
while (tok != nullptr) {
string stok = tok;
trim(stok);
result.push_back(stok);
tok = strtok(nullptr, sep);
}
return result;
}

int main() {
size_t n;
cin >> n;
cin.ignore(numeric_limits::max(), '\n');
map vocab;
for (size_t i = 0; i < n; i++) {
string s;
getline(cin, s);
auto entry = split(s, "-");
if (entry.size() == 2) {
vocab[entry[0]] = split(entry[1], ", ");
} else {
cerr
Антон Мишин
Антон Мишин
87 571
Лучший ответ
Например, так:
 #include 
#include
#include
#include

using namespace std;

// Образание пробелов на концах слова
string &trim(string &s) {
stringstream trimmer;
trimmer > s;
return s;
}

// Преобразование строки разделённых запятыми слов в множество слов
set parse(string &buf) {
set result;
stringstream s(buf);
string temp;

while (getline(s, temp, ',')) {
result.insert(trim(temp));
}

return result;
}

int main() {
int n;
map inp, out;
set lat;

// Ввод англо-латинского словаря, формирование множества всех латиских слов
cin >> n;
for (int i = 0; i < n; ++i) {
string key, temp;
getline(cin, key, '-');
getline(cin, temp);
auto list = parse(temp);
inp[trim(key)] = list;
lat.insert(list.begin(), list.end());
}

// Заполнение латинско-английского словаря латинским словами
for (auto word : lat) { out[word] = set(); }

// Заполнение латинско-английского словаря английскими словами
for (auto row : inp) {
for (auto word: get(row)) { out[word].insert(get(row)); }
}

// Вывод латинско-английского словаря
for (auto row : out) {
cout
Eвгений Hammel
Eвгений Hammel
53 565