Top.Mail.Ru
Ответы
Аватар пользователя
Аватар пользователя
Аватар пользователя
Аватар пользователя
Программирование
+4

Помогите решить задачу 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, потому что он справляется с ситуациями когда в потоке ввода остаётся несколько разделительных символов и нам точно неизвестно какие это символы и сколько их.

По дате
По рейтингу
Аватар пользователя
Новичок

Можно сделать так:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
 #include <iostream>
#include <limits>
#include <cstring>
#include <string>
#include <vector>
#include <map>

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<string> split(const string &s, const char *sep) {
    char* cstr = const_cast<char*>(s.c_str());
    char *tok = strtok(cstr, sep);
    vector<string> 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<streamsize>::max(), '\n');
    map<string, vector<string>> 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 << "Некорректная строка" << endl;
        }
    }

    map<string, vector<string>> reverse;
    for (const auto &p : vocab) {
        for (const auto &w : p.second) {
            reverse[w].push_back(p.first);
        }
    }

    for (const auto &p : reverse) {
        cout << p.first << ": ";
        const char *delim = "";
        for (const auto &w : p.second) {
            cout << delim << w;
            delim = ", ";
        }
        cout << endl;
    }

    return 0;
} 
Аватар пользователя
Высший разум

Например, так:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
 #include <iostream>
#include <sstream>
#include <map>
#include <set>

using namespace std;

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

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

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

    return result;
}

int main() {
    int n;
    map<string, set<string>> inp, out;
    set<string> 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<string>(); }

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

    // Вывод латинско-английского словаря
    for (auto row : out) {
        cout << get<0>(row);
        bool flg = false;
        for (auto word: get<1>(row)) {
            cout << (flg ? ", " : " - ") << word;
            flg = true;
        }
        cout << '\n';
    }

    return 0;
}