计算带向量的元素出现次数

时间:2013-04-11 09:02:18

标签: c++ vector

我正在学习C ++(正确),通过我自己的Andrew Koenig和Barbara Moo的书“Accelerated C ++”,并在每一章中进行所有练习。

练习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;
}

使用矢量有更好的方法吗?通过组合任何循环可以使代码更高效吗?

2 个答案:

答案 0 :(得分:1)

对我有用的解决方案(当我解决这个问题时)是使用三个向量:input_vectoroutput_vectorcount_vector。使用while使用std::cin阅读用户输入,直到输入转义字符:使用input_vector.push_back(input_word)用文字填充input_vector。使用std::sort中的<algorithm>对矢量进行排序,然后创建output_vector(包含一个值,input_vector中的第一个单词)和count_vector(包含一个值, 1)。

然后,对于input_vector中的每个元素(从第二个开始,而不是第一个),检查当前元素是否与最后一个元素相同。如果是,请将1添加到count_vector中的当前元素。否则,使用input_vectoroutput_vector中的当前单词添加到push_back(),并将count_vector的大小增加一个元素(其值为1)。

答案 1 :(得分:0)

如果你想象某人正在使用你的代码来处理莎士比亚的整个作品,你会因为存储每一个字而浪费大量的空间。如果您改为使用“单词”和“单词计数”的结构,您只需要存储单词“the”一次,即使它在您的程序输入的文本中出现了100000次。也就是说,如果您甚至需要知道该单词已经出现过多次 - 如果您只需要一个唯一单词列表,那么您只需要查看是否已经存储了该单词。 [以排序顺序存储它们可以使用binary_search来查找它们,如果您确实通过代码运行莎士比亚的800K(非唯一)单词,这将有助于运行时间