首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >加速C++练习8-5解决方案不清楚

加速C++练习8-5解决方案不清楚
EN

Stack Overflow用户
提问于 2011-12-18 13:08:38
回答 1查看 1.1K关注 0票数 6

我被困在解决加速的C++练习8-5,我不想错过在这本书中的一个练习。

加速C++练习8-5如下:

重新实现了第7章中的gen_sentencexref函数,以使用输出迭代器,而不是将整个输出放在一个数据结构中。通过编写直接将输出迭代器附加到标准输出的程序,并将结果分别存储在list <string>map<string, vector<int> >中,来测试这些新版本。

要理解这个问题的范围和本书本部分中的当前知识,本练习是关于模板中的泛型函数模板和迭代器使用的章节的一部分。之前的练习是实现<algorithm>库函数的简单版本,如equal, find, copy, remove_copy_if等。

如果我正确理解,我需要修改xref函数,以便:

iterator

  • Store map<string, vector<int> >

中的

  • 使用输出结果

我试图将映射迭代器作为back_inserter().begin().end()传递给这个函数,但是无法编译它。回答here解释了原因。

xref函数,如第7章所示:

代码语言:javascript
运行
复制
// find all the lines that refer to each word in the input
map<string, vector<int> >
    xref(istream& in,
         vector<string> find_words(const string&) = split)
{
    string line;
    int line_number = 0;
    map<string, vector<int> > ret;

    // read the next line
    while (getline(in, line)) {
        ++line_number;

        // break the input line into words
        vector<string> words = find_words(line);

        // remember that each word occurs on the current line
        for (vector<string>::const_iterator it = words.begin();
             it != words.end(); ++it)
            ret[*it].push_back(line_number);
    }
    return ret;
}

分阶段执行:

代码语言:javascript
运行
复制
vector<string> split(const string& s)
{
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i = 0;

    // invariant: we have processed characters `['original value of `i', `i)'
    while (i != s.size()) {
        // ignore leading blanks
        // invariant: characters in range `['original `i', current `i)' are all spaces
        while (i != s.size() && isspace(s[i]))
            ++i;

        // find end of next word
        string_size j = i;
        // invariant: none of the characters in range `['original `j', current `j)' is a space
        while (j != s.size() && !isspace(s[j]))
            ++j;

        // if we found some nonwhitespace characters
        if (i != j) {
            // copy from `s' starting at `i' and taking `j' `\-' `i' chars
            ret.push_back(s.substr(i, j - i));
            i = j;
        }

    }
    return ret;
}

请帮助我理解我错过了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-18 13:41:31

我找到了关于这个练习的更多细节,在这里:https://stackoverflow.com/questions/5608092/accelerated-c-exercise-8-5-wording-help

模板void gen_sentence( const语法& g,string s,out和out)

使用:

std::ostream_iterator out_str (std::cout,“");gen_sentence( g,"",out_str );

模板 void (入、入、出和出,向量find_words( const &)= split )

使用:

std::ostream_iterator out_str (std::cout,“");

坦率地说,我必须得出这样的结论:这个问题是不恰当的,特别是在他们为xref:xref指定了新接口的地方,xref应该产生一个映射。但是,在这种情况下,使用输出迭代器将意味着使用std::inserter(map, map.end())。虽然您可以编写代码的编译版本,但这不能如您所期望的那样做,因为map::insert将简单地忽略带有重复键的任何插入。

如果xref的目标仅仅是将单词链接到它们第一次出现的行号,这仍然可以,但我有一种感觉,练习的作者忽略了下面这个更微妙的点:)

下面是代码(请注意,我为split发明了一个愚蠢的实现,因为它既缺少也需要):

代码语言:javascript
运行
复制
#include <map>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <iterator>

std::vector<std::string> split(const std::string& str)
{
    std::istringstream iss(str);
    std::vector<std::string> result;
    std::copy(std::istream_iterator<std::string>(iss),
              std::istream_iterator<std::string>(),
              std::back_inserter(result));

    return result;
}

// find all the lines that refer to each word in the input
template <typename OutIt>
OutIt xref(std::istream& in,
        OutIt out,
        std::vector<std::string> find_words(const std::string&) = split)
{
    std::string line;
    int line_number = 0;

    // read the next line
    while (getline(in, line)) {
        ++line_number;

        // break the input line into words
        std::vector<std::string> words = find_words(line);

        // remember that each word occurs on the current line
        for (std::vector<std::string>::const_iterator it = words.begin();
             it != words.end(); ++it)
            *out++ = std::make_pair(*it, line_number);
    }

    return out;
}

int main(int argc, const char *argv[])
{
    std::map<std::string, int> index;

    std::ifstream file("/tmp/test.cpp");
    xref(file, std::inserter(index, index.end()));

#if __GXX_EXPERIMENTAL_CXX0X__
    for(auto& entry: index)
        std::cout << entry.first << " first found on line " << entry.second << std::endl;
#else
    for(std::map<std::string, int>::const_iterator it = index.begin();
        it != index.end();
        ++it)
    {
        std::cout << it->first << " first found on line " << it->second << std::endl;
    }
#endif

    return 0;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8551922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档