Мы начинаем переходить с C на C ++ в моем классе программирования, и наше текущее лабораторное задание состоит в том, чтобы создать программу, которая с помощью текстового файла читает его содержимое, а затем возвращает список слов в файле вместе с номером строки, с которой они появляются. и число раз, когда это слово появляется в каждой строке, в формате Word Line: Count.
Foo bar bar
Baz
Foo
<EOF>
Который должен вернуться:
Foo 1:1 3:1
Bar 1:2
Baz 2:1
Единственными структурами данных, которые мы рассмотрели, являются карты, с помощью которых мы написали следующую программу, которая выводит общее количество слов
int main(int argc, const char*argv[]) {
map<string, unsigned int> table;
string word;
while (cin >> word) {
++table[word];
}
for (std::map<string, unsigned int>::iterator itr = table.begin();
itr != table.end(); ++itr) {
cout << itr->first << "\t" << itr->second << endl;
}
return 0;
}
Нам сказали, что можно было бы изменить эту программу (немного) минимально, чтобы она распечатала номер строки и количество слов. У меня вопрос, есть ли способ использовать карту, чтобы иметь 2 значения для каждого ключа? Или есть лучший способ реализовать что-то подобное?
Вы можете хранить в своей карте почти все что угодно в качестве значения ключа. Чтобы иметь возможность подсчитать, сколько раз слово появляется и вести динамический список номеров строк, на которых оно появляется, вы можете сделать следующее. Это самое простое и понятное решение, которое пришло ко мне, оно не самое эффективное.
Используйте карту со строковым ключом и вектором значений для хранения, index = WordLine, значение при index = Count
#include <vector> // std::vector
using namespace std;
map<string, vector<int>> words;
Когда вы сталкиваетесь со словами, ищите их на карте и увеличивайте вектор по индексу line_num, чтобы обозначить, сколько раз оно встречается в строке.
#include <sstream>
using namespace std;
string line;
string word;
int line_num = 0;
while (getline(cin, line)) {
istringstream words_iss(line);
while(line >> word) {
++words.at(word)[line_num];
}
++line_num;
}
Неэффективность возникает из-за использования индекса для представления номера строки, поскольку слово может не отображаться до строки n. Однако, когда он помещает его в вектор с индексом n, он собирается выделить пространство для 0 — (n-1) -данных для вектора. Также при печати вам нужно будет проверить каждое значение в векторе, чтобы убедиться, что оно не равно 0.
Вы можете печатать, просматривая каждую строку на карте, затем просматривая вектор каждого ключа и печатая, только когда значение в индексе не равно 0.
Как упомянуто в комментариях, другим решением будет использование
map<string, map<int, int>>
с похожей логикой. Что было бы более эффективным для большинства случаев.