Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

c++ - 有条件地打印和计数std :: map有限制(Conditional printing and counting over std::map with restrictions)

I am currently in the process of learning C++17 and we were given a challenge as part of practicing using the Standard library to get used to using the features:

(我目前正在学习C ++ 17,作为练习使用标准库以习惯使用这些功能的一部分,我们遇到了挑战:)

  1. Iterate over a std::map<std::string, size_t> (also known as std::map<file_name, file_size> )

    (遍历std::map<std::string, size_t> (也称为std::map<file_name, file_size> ))

  2. Print file names that are empty size_t == 0 and return its count

    (打印为空的文件名size_t == 0并返回其计数)

  3. Print file names that are not empty size_t != 0 and return its count

    (打印不为空的文件名size_t != 0并返回其计数)

  4. Removing from map std::pairs whose size_t == 0

    (从map std::pairs删除, whose size_t == 0)

Restrictions:

(限制条件:)

  1. Can only use headers: <vector> , <map> , <string> , <algorithm> , <functional>

    (只能使用标头: <vector><map><string><algorithm><functional>)

  2. Cannot define complex types nor templates

    (无法定义复杂类型或模板)

  3. Cannot use the . (member access), -> (member access via pointer), * (dereference) operators

    (无法使用. (member access), -> (member access via pointer), * (dereference) operators) . (member access), -> (member access via pointer), * (dereference) operators

  4. Cannot use for, while, do-while nor if-else, switch and other conditionals

    (不能for, while, do-while nor if-else, switch和其他条件)

  5. Can use std::for_each and other functions of function templates to iterate over collection of elements

    (可以使用std::for_each和功能模板的其他功能来迭代元素集合)

  6. No lambdas

    (没有lambdas)

  7. No std::cout , std::cerr , std::ostream etc.

    (没有std::coutstd::cerrstd::ostream等。)

  8. No auto types

    (没有自动类型)

  9. Can use other functions so long as they are included in the headers described at restriction #1

    (可以使用其他功能,只要它们包含在限制1中所述的标头中)

Allowed to use these functions:

(允许使用以下功能:)

void print(const std::string& str)
{
    std::cout << str << std::endl;
}
std::string split(const std::pair<std::string, size_t> &r)
{
    std::string name;
    std::tie(name, std::ignore) = r;
    return name;
}
bool checkEmpty(const std::pair<std::string, size_t>& r, bool trueIfIsNot
)
{
    file_size size;
    std::tie(std::ignore, size) = r;
    bool result = (size == 0);
    if (trueIfIsNot)
    {
        result = !result;
    }
    return result;
}

I have began to appreciate the use of std::bind and std::for_each in my previous post.

(在我以前的文章中,我开始欣赏std::bindstd::for_each的使用。)

This time, how do i add predicates and conditionals to modify the output without using syntax stated by restriction #4?

(这次,我如何添加谓词和条件以修改输出,而无需使用限制#4所述的语法?)

I am currently considering using std::transform() or maybe std::copy_if() etc. I have some understanding of many of the Standard Library's functions but i think i am very weak at the syntax to understand how things work together so i do not know how to make use of them.

(我目前正在考虑使用std::transform()std::copy_if()等。我对许多标准库的功能都有一定的了解,但是我认为我在语法上很虚弱,无法理解事情如何协同工作,所以我不知道如何利用它们。)

  ask by eglades translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For 2,3 tasks you could do:

(对于2,3个任务,您可以执行以下操作:)

  • use vector with initial size as map size

    (使用初始大小的vector作为地图大小)

  • use copy_if to copy elements from map depending on condition

    (根据条件使用copy_if从地图复制元素)

  • use for_each with bounded split / print

    (使用for_each进行有限split / print)

  • return number of items as difference between first and last item in vector

    (返回项目数作为向量中第一项和最后一项之间的差)

The code:

(代码:)

int task2and3(const std::map<std::string,int>& m, bool trueIfIsNot)
{
    std::vector<std::pair<std::string,int>> vec(m.size());
    auto firstPastEnd = std::copy_if(m.begin(),m.end(),vec.begin(),
        std::bind(checkEmpty,std::placeholders::_1,trueIfIsNot));

    std::for_each(vec.begin(), firstPastEnd, 
        std::bind(print,std::bind(split,std::placeholders::_1)));

    return firstPastEnd - vec.begin();
}

by trueIfIsNot you indicate which pairs are printed (with value as 0 or otherwise).

(通过trueIfIsNot指示要打印的对(值等于0或其他值)。)


To do 4-th task, you could also use vector to store items of map .

(要执行第4项任务,您还可以使用vector存储map项目。)

To remove elements from map you could iterate over these items in vector (using for_each ) and call map::erase method.

(要从map中删除元素,您可以遍历vector中的这些项目(使用for_each )并调用map::erase方法。)

Because this function member has overloads, you need to cast it properly to indicate method removing elements by key_type .

(由于此函数成员具有重载,因此需要正确地对其进行key_type以指示通过key_type删除元素的key_type 。)

Use split to get this key_type from pair.

(使用split从对中获取此key_type 。)

void task4(std::map<std::string,int>& m)
{
    std::vector<std::pair<std::string,int>> vec(m.size());
    auto firstPastEnd = std::copy_if(m.begin(),m.end(),vec.begin(),std::bind(checkEmpty,std::placeholders::_1,false));

    using sizeType = std::map<std::string,int>::size_type;
    using keyType = std::map<std::string,int>::key_type;

    for_each(vec.begin(), firstPastEnd, 
        std::bind( static_cast<sizeType (std::map<std::string,int>::*)(const keyType&) >(&std::map<std::string,int>::erase),
        &m,
        std::bind(split,std::placeholders::_1)) );
}

Full demo

(完整演示)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...