C/C++

Помогите написать программу на C++

Тема: Словари и множества,
map и set.

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

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

Вам дан словарь, которым пользовался Вася и домашнее задание, сданное Петей. Ваша задача — определить количество ошибок, которое в этом задании насчитает Вася.

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

Вводится сначала число N — количество слов в словаре (0 ≤ N ≤ 20000).

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

Далее идет упражнение, выполненное Петей. Упражнение представляет собой строку текста, суммарным объемом не более 300000 символов. Строка состоит из слов, которые разделяются между собой ровно одним пробелом. Длина каждого слова не превышает 30 символов. Все слова состоят из маленьких и заглавных латинских букв (заглавными обозначены те буквы, над которыми Петя поставил ударение). Петя мог по ошибке в каком-то слове поставить более одного ударения или не поставить ударения вовсе.

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

Выведите количество ошибок в Петином тексте, которые найдет Вася.

Примечание к примеру


1. В слове cannot, согласно словарю возможно два варианта расстановки ударения. Эти варианты в словаре могут быть перечислены в любом порядке (т.е. как сначала cAnnot, а потом cannOt, так и наоборот).
Две ошибки, совершенные Петей — это слова be (ударение вообще не поставлено) и fouNd (ударение поставлено неверно). Слово thE отсутствует в словаре, но поскольку в нем Петя поставил ровно одно ударение, признается верным.

2. Неверно расставлены ударения во всех словах, кроме The (оно отсутствует в словаре, в нем поставлено ровно одно ударение). В остальных словах либо ударные все буквы (в слове PAGE), либо не поставлено ни одного ударения.


Sample Input 1:

4
cAnnot
cannOt
fOund
pAge
thE pAge cAnnot be fouNd
Sample Output 1:

2
Sample Input 2:

4
cAnnot
cannOt
fOund
pAge
The PAGE cannot be found
Sample Output 2:

4
Сергей __
Сергей __
89
#include <iostream>
#include <sstream>
#include <map>
using namespace std;

string lower_w(const string& word)
{
string newstr(word);
for (auto& i : newstr) i = tolower(i);
return newstr;
}

bool compare_w(const multimap<string, string> deadmoroz, const string word)
{
auto d_it = deadmoroz.equal_range(lower_w(word));
while (d_it.first != d_it.second)
{
if (word == d_it.first->second) return true;
d_it.first++;
}
return false;
}

bool is_normal(const string& word)
{
uint16_t count{};
for (auto& i : word)
{
count += i != tolower(i);
if (count == 2) return false;
}
return count==1;
}

int main()
{
multimap<string, string> deadbeef;
uint16_t number{}, error_number{};
cin >> number;
string word;
for (uint16_t i = 0; i < number; i++)
{
cin >> word;
deadbeef.emplace(lower_w(word), move(word)); //<lower, normal>
}
cin.ignore();
getline(cin, word); //now word is str
istringstream str(word);
while (str >> word)
{
if (!is_normal(word)) { error_number++; continue; }
if (!deadbeef.count(lower_w(word))) continue; //not in chicken and normal = 0 err;
error_number += !compare_w(deadbeef, word);
}
cout << "\n\n" << error_number;
}

С вас 199.99 уе
Богдан Дорофеев
Богдан Дорофеев
51 416
Лучший ответ
Богдан Дорофеев Да, кстати, можно обойтись без мультимапы, мапы вообще, и уменьшить потребление памяти. Но будет медленнее и на это понадобится еще 1000 уе и неделя time)
Ученик Петя не смог дочитать это задание, и от скуки повесился
Как же многословен C++, так много кода и почти невозможно его понять? на Python данная задача решается существенно легче, кода раз в 5 меньше, время на составление решения и отладку кода также в разы меньше, чем на плюсах.
код на Python:
 words = dict() 
for _ in range(int(input())):
word = input()
words.setdefault(word.lower(), set()).add(word)
result = 0
for word in input().split():
key = word.lower()
if key in words and word not in words[key] or sum(char.isupper() for char in word) != 1:
result += 1
print(result)
Пытаюсь решить данную задачу на плюсах, смотрю на данный код и не понимаю его: работа с указателями, использование типа данных uint16_t (что это за тип?), что за словари multimap, почему нельзя использовать просто map? название переменных для словарей то еще: deadbeef, deadmoroz, чтение данных не просто через cin, а с каким то извращением, использование istringstream str(word); while (str >> word) я так понял это просто сплит слов (разделение предложения на слова по разделителю пробел) но не просто обычный split() как в Python, а что то извращенное. Плюсы только начал изучать, данный код мне не понятен, чтобы решить задачу средствами C++, нужно еще многое изучить