对于每个单词输出对的列表,该行的行号和字数

时间:2015-04-13 19:00:15

标签: c++ string dictionary stdin std-pair

我试图为stdin中的每个单词编写程序,输出L:N形式的对列表,其中L是行号,N是给定单词的出现次数。

所以如果stdin是:

hello world
hello hello

输出应为

hello 1:1 2:2
world 1:1

在下面的代码中

#include <iostream>
#include <map>
#include <string>
#include <iterator>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::map;
using std::pair;


int main(int argc, const char *argv[])
{
    map<string, pair<unsigned int, unsigned int>> table;
    string word;
    while (cin >> word) {
        ++table[word];
    }
    for (std::map<string, pair<unsigned int, unsigned int>>::iterator itr = table.begin(); itr != table.end();
        ++itr) {
        cout << itr->first << "\t => \t" << itr->second << itr->third << endl;
    }
    while (cin >> word) {
        ++table[word];
    }
}

我试图创建一个使用三个元素的地图,并且有一个可以遍历地图的迭代器,并计算行数并使用getline()来获取a的出现次数每行上的字。此代码只输出总字数。

2 个答案:

答案 0 :(得分:0)

为了帮助您入门,我建议您使用map,其中包含行号和匹配项的结构:

struct Word_Attributes
{
  unsigned int line_number;
  unsigned int occurances_on_line;
};

typedef std::vector<Word_Attributes> Attribute_Container;

typedef std::map<string, Attribute_Container> Dictionary;  

int main(void)
{
  Dictionary  my_words;
  std::string text_line;
  unsigned int line_number = 1;
  // Read in text lines until EOF or failure.
  while (getline(cin, text_line)
  {
    // Extract words from the text line.
    std::string        word;
    std::istringstream text_stream(text_line);
    while (text_stream >> word)
    {
      // A word is extracted.  
      // See if it is in the dictionary.
      Dictionary::iterator  iter;
      iter = my_words.find(word);

      // If the word is in the dictionary, check for attributes.
      if (iter != my_words.end())
      {
        // use iter to get the property list.
        // Check the property list for the line number.
        // If line number exists, increment the occurrances.
        // Otherwise, create a new attributes structure and
        //    append to the property list.
      }
      else
      {
        // The word is not in the dictionary,
        //   create an initial attributes structure for the word.
        Word_Attributes  attributes;
        attributes.line_number = line_number;
        attributes.occurances_on_line = 1;
        Attribute_Container  property_list;
        property_list.push_back(attributes);
        my_words[word] = property_list;
      }
    }
  }
  return EXIT_SUCCESS;
}

以下是一些属性/规则:

  • 每个单词都有一个或多个与该单词相关联的行号。
  • 该单词的每个行号都有多次出现。

输入:

[1]  hello world
[2]  hello hello

您应该看到:

hello ---> Line 1, occurrences: 1  
  |   +--> Line 2, occurrences: 2  
  V
world ---> Line 1, occurrences: 1

完成上面的模板是读者的练习。

答案 1 :(得分:0)

我会用这个容器来表示数据:

//           word               line   count
std::map<std::string, std::map<size_t, size_t>> wordCounts;

内部地图作为更便宜的数据结构会更优化,但是根据您的性能要求,您可能会喜欢这样,因为它非常容易使用(您需要编写更少的代码)。例如,当您解析一个新单词并拥有其行号时,您只需更新数据结构即可:

++wordCounts[word][lineNumber];

没有比这简单得多。如果结构中的单词或行号不是已添加,如果是,则使用已经存在的内容。

填写它会看起来像这样:

std::string line;
for(size_t lineNumber = 1; std::getline(std::cin, line); ++lineNumber)
{
    std::istringstream ss{line}
    for(std::string word; ss >> word;)
        ++wordCounts[word][lineNumber];
}