2010-09-29 5 views
2

Я работаю на упражнение с Accelerated C++:сосчитать, сколько раз появляется каждый отдельный слово на входе

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

Вот мой код:

#include <iostream> 
#include <string> 
#include <vector> 

int main() 
{ 
    // Ask for 
    // and read the input words 
    std::cout << "Please input your words: " << std::endl; 
    std::vector<std::string> word_input; 
    std::string word; 
    int count = 0; 
    while (std::cin >> word) 
    { 
     word_input.push_back(word); 
     ++count; 
    } 

    // Compare the input words 
    // and output the times of every word compared only with all the words 

    /***** I think this loop is causing the problem ******/ 
    for (int i = 0; i != count; ++i) 
    { 
     int time = 0; 
     for (int j = 0; j != count; ++j) 
     { 
      if (word_input[i] == word_input[j]) 
       ++time; 
      else 
       break; 
     } 

     std::cout << "The time of " 
        << word_input[i] 
        << " is: " 
        << time 
        << std::endl; 
    } 

    return 0; 
} 

Если скомпилировать и запустить эту программу, вы увидите:

Please input your words:

И вход следующим образом:

 
good good is good 
EOF 

Тогда он показывает:

 
The time of good is: 2 
The time of good is: 2 
The time of is is: 0 
The time of good is: 2 

Мой ожидаемый результат:

 
The time of good is: 3 
The time of is is: 1 

Я не хочу, чтобы использовать карту, потому что я не узнал, что до сих пор.

В чем причина этого неожиданного поведения и как его исправить?

ответ

3

Предполагая, что зЬй :: вектор является единственным контейнером вы знакомы с в этой точке, и что вы еще не дошли до StD :: пара все же, я предлагаю следующее:

  • добавить a std::vector<int> word_count
  • в вашем std::cin while-loop, вы проверяете, присутствует ли текущее слово в word_input. Если это не так, вы найдете push_back слово и push_back a 1 в word_count. Если уже есть запись для текущего слова с некоторым индексом i в word_input, вы увеличиваете word_count по этому индексу i. Таким образом, каждое отдельное слово, которое вы вводите, появляется только после в word_input, с количеством раз, когда это было управление вводом word_count.
  • для вывода, шаг за шагом word_input и word_count параллельно и выводить количество слов для каждого слова.

Выполнено.

Но все это становится намного проще и элегантнее с std::map. Продолжай читать! :-)

1

Просто удалите инструкцию else.

int main() 
{ 
    // Ask for 
    // and read the input words 
    std::cout << "Please input your words: " 
       << std::endl; 
    std::vector<std::string> word_input; 
    std::string word; 
    int count = 0; 
    while (std::cin >> word) 
     { 
      word_input.push_back(word); 
      ++count; 
     } 

    // Compare the input words 
    // and output the times of every word compared only with all the words 
    for (int i = 0; i != count; ++i) 
     { 
      int time = 0; 
      for (int j = 0; j != count; ++j) 
       { 
        if (word_input[i] == word_input[j]) 
         ++time; 
        // else   <========== You don't need this! 
        // break; 
       } 

      std::cout << "The time of " 
       << word_input[i] 
       << " is: " 
       << time 
       << std::endl; 
     } 

    return 0; 
} 

Обратите внимание, что ваше решение очень медленно для больших входов. Лучшей идеей было бы использовать hashtable (std :: map) для вашего словаря или отсортировать этот вектор, а не считать разные слова (выполняется в O (logN * N), ваше решение - O (N^2)).

+0

std :: map не реализован как хэш-таблица, поэтому он все равно будет медленным. См. Stdext :: hash_map или новый std :: tr1 :: unordered_map. –

+0

Я не хочу использовать карту, потому что я не узнал, что ~ Я только что узнал 3 главы. И я только что редактировал мой вопрос. Может быть, вы не поняли, чего я хочу.Спасибо вам все равно ~ – Darson

+0

@ Mark Ingram: Или, альтернативно, 'boost :: unordered_map' для старых компиляторов. – lunaryorn

Смежные вопросы