В настоящее время я изучаю C++ (правильно), просматривая книгу Ускоренный C++ от Andrew Koenig и Barbara Moo самостоятельно и выполняя все упражнения в каждой главе.Подсчитайте количество вхождений элементов с векторами
Упражнение 3-3: Напишите программу, чтобы подсчитать, сколько раз каждое отдельное слово появляется на своем входе. Для меня это упражнение представлялось чрезвычайно сложным, особенно учитывая: 1. Примеры и другие упражнения в этой главе были относительно простыми и 2. Вам разрешено использовать только векторы, поэтому ничего не продвинулось. (или, может быть, это просто я неправильно оцениваю сложность)
Я искал в Интернете подсказки и видел, что у других возникли проблемы с этим упражнением, но решения, предлагаемые людьми, казались мне непонятными. Большинство людей предложили использовать организационные методы, которые вводятся позже в книге, и это то, что поражает точку упражнения. Наконец, я кусочкам намеки и биты методов, которые я нашел на разных форумах (в том числе и здесь), чтобы придумать с моим собственным решением:
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
using std::cin;
using std::setprecision;
using std::cout;
using std::string;
using std::endl;
using std::streamsize;
using std::sort;
using std::vector;
int main()
{
// Ask for string input
cout << "Please write some text, followed by end-of-file: " << endl;
vector<string> word_input;
string word;
// input words into string vector word_input
typedef vector<string>::size_type vecsize;
while (cin >> word)
{
word_input.push_back(word);
}
// sort the vector in alphabetical order to be able to separate distinct words
sort(word_input.begin(),word_input.end());
// create two vectors: one where each (string) element is a unique word, and one
// that stores the index at which a new distinc word appears
vector<string> unique_words;
vector<int> break_index;
for (int i=0; i != word_input.size()-1; ++i)
{
if(word_input[i+1] != word_input[i])
{
unique_words.push_back(word_input[i]);
break_index.push_back(i);
}
}
// add the last word in the series to the unique word string vector
unique_words.push_back(word_input[word_input.size()-1]);
// create a vector that counts how many times each unique word occurs, preallocate
// with 1's with as many times a new word occurs in the series (plus 1 to count the first word)
vector<int> word_count(1,break_index[0]+1);
// if a new word occurs, count how many times the previous word occured by subtracting the number of words so far
for(int i=0; i != break_index.size()-1;++i)
{
word_count.push_back(break_index[i+1] - break_index[i]);
}
// add the number of times the last word in the series occurs: total size of text - 1 (index starts at 0) - index at which the last word starts
word_count.push_back(word_input.size()-1-break_index[break_index.size()-1]);
// number of (distinct) words and their frequency output
cout << "The number of words in this text is: " << word_input.size() << endl;
cout << "Number of distinct words is: " << unique_words.size() << endl;
// The frequency of each word in the text
for(int i=0; i != unique_words.size(); ++i)
cout << unique_words[i] << " occurs " << word_count[i] << " time(s)" << endl;
return 0;
}
Есть ли лучший способ сделать это с помощью векторов? Может ли код быть более эффективным, комбинируя любые петли?
Это лучше подходит для [Обзор кода] (http://codereview.stackexchange.com/). – jrok
Stackoverflow - это не сайт для просмотра кода. Мое мнение таково, что ваш отпечаток и использование пространств вокруг операторов странно непоследовательны. Вы можете консолидировать часть своей работы, используя std :: unique от, который удаляет последовательные неединичные элементы между двумя итераторами (которые будут удалять дубликаты из списка слов) –
Wug
ну, только очень быстро сканируя ваш код, вы потратили довольно много логики для этого. Это должен быть только контейнер (список/вектор), цикл, повторяющий все слова, и 'if (std :: find())' в вашем текущем контейнере, если он уже содержит слово (если нет, вставьте его где угодно желание). Общее количество слов можно легко получить через контейнер.size() и не должен быть сохранен сам по себе (не то, что он болит много, его просто не обязательно) – Najzero