Поиск символа в строке в векторе

Судя по названию, я сделал свою программу довольно сложным способом. НО! Я бы все равно спросил xD

Это простая программа, которую я написал в ответ на вопрос 3-3 книги Accelerated C++, которая, на мой взгляд, является отличной книгой.

Я создал вектор:

vector<string> countEm;

Это принимает все допустимые строки. Поэтому у меня есть вектор, содержащий элементы строк.

Далее я создал функцию

int toLowerWords( vector<string> &vec )
{
    for( int loop = 0; loop < vec.size(); loop++ )
        transform( vec[loop].begin(), vec[loop].end(),
            vec[loop].begin(), ::tolower );

который разбивает ввод на все символы нижнего регистра для облегчения подсчета. Все идет нормально.

Я создал третью и последнюю функцию для фактического подсчета слов, и здесь я застрял.

int counter( vector<string> &vec )
{

for( int loop = 0; loop < vec.size(); loop++ )
    for( int secLoop = 0; secLoop < vec[loop].size(); secLoop++ )
    {
        if( vec[loop][secLoop] == ' ' )

Это просто смешно выглядит. Использование двумерного массива для вызова символов вектора, пока я не найду пробел. Нелепый. Я не верю, что это элегантное или даже жизнеспособное решение. Если бы это было жизнеспособным решением, я бы отступил от пробела и скопировал все символы, которые я нашел, в отдельный вектор и подсчитал этих.

Тогда мой вопрос. Как я могу разбить вектор строк на отдельные слова, чтобы я мог их посчитать? Я думал об использовании strchr, но это не дало мне никаких прозрений.


Решение через Нила:

stringstream ss( input );
while( ss >> buffer )
    countEm.push_back( buffer );

Из этого я мог легко сосчитать (повторяющиеся) слова.

Затем я сделал решение через Вильгельма, которое я опубликую, как только перепишу его, так как я случайно удалил это решение! Глупо с моей стороны, но я опубликую это, как только снова напишу ^^

Я хочу поблагодарить всех вас за ваш вклад! Решения сработали, и я стал немного лучше программировать. Если бы я мог проголосовать за ваши вещи, я бы сделал это :P Как только я смогу, я это сделаю! И еще раз спасибо!


person IAE    schedule 19.04.2010    source источник


Ответы (3)


Если слова всегда разделены пробелами, самый простой способ разделить их — использовать строковый поток:

string words = ....   // populat
istringstream is( words );

string word;
while( is >> word ) {
   cout << "word is " << word << endl;
}

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

person Community    schedule 19.04.2010
comment
Привет! Я никогда не использовал istringstream, поэтому я действительно не знаю, с какой магией вы здесь работаете, но я дам вам знать, если смогу решить проблему с помощью этого решения ^^ Так что спасибо за это! Как и в предыдущем случае, я отмечу положительный результат, как только у меня будет на это разрешение. - person IAE; 19.04.2010

Вы можете использовать std::istringstream для извлечения слов одно за другим и их подсчета. Но это решение требует O(n) пространственной сложности.

string text("So many words!");
size_t count =  0;
for( size_t pos(text.find_first_not_of(" \t\n"));
    pos != string::npos;
    pos = text.find_first_not_of(" \t\n", text.find_first_of(" \t\n", ++pos)) )
    ++count;

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

person wilhelmtell    schedule 19.04.2010
comment
Спасибо за ответ ^^ Я пока не могу голосовать, поэтому отвечу на ваш ответ. Я не слышал часть синтаксиса, который вы используете, поэтому я немного изучаю его и дам вам знать, как я с ним справляюсь, но спасибо за помощника! - person IAE; 19.04.2010
comment
Кроме семантической ошибки, которая у меня была (text::npos вместо string::npos, которую я только что исправил), в синтаксисе нет ничего особенного. Возможно, вас смутил отступ... На самом деле это простой цикл for. - person wilhelmtell; 21.04.2010
comment
... и логическая ошибка. фу, я действительно должен проверить свой код, прежде чем опубликовать его. :с - person wilhelmtell; 21.04.2010
comment
Ничего страшного, я разобрался с проблемами, когда подошла моя очередь писать. Ваше решение все еще было в силе, так что ура и спасибо! Я опубликую его в редактировании, чтобы другие люди могли видеть, как только я перепишу его. Спасибо! - person IAE; 21.04.2010

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

person jilles de wit    schedule 19.04.2010
comment
Эй, Джайлс! Я начал читать об этом и подумал об использовании токенизатора, но я нашел strchr, прежде чем смог найти strtok и его более безопасный эквивалент. Я также дам вам знать, смогу ли я ответить на него с помощью этого решения, так как я хочу использовать их все в качестве возможного ответа, чтобы позже я мог быть максимально универсальным ^^ - person IAE; 19.04.2010