python里有一个东西,叫map。

它可以实现像这样,对list每个元素进行操作,并返回新的list(python3是迭代器)

像这样

a=list(map(int,input().split()))
b=list(map(lambda x:x*2,a))

遇到这个,我们就会像:c++可不可以也搞一个,对vector每个元素进行操作的函数?

emm,就叫my_map好了。

有了想法,那就开干呗!

老样子,先放成品(完整程序和注释版在后面)

template<typename Ori,typename Func_Type>
auto my_map(Func_Type my_func,vector<Ori> &x){
using return_type = typename result_of<Func_Type(Ori)>::type;
vector<return_type> tmp;
for(auto i :x)
tmp.push_back(my_func(i));
return tmp;
} int main()
{
auto s=input().split();
cout<<s; auto a=my_map(my_int,s);//my_int是函数,string转int
cout<<a; auto b=my_map(Dao_Shu(),a);//Dao_Shu是一个重载了()的类(结构体)
cout<<b; auto ping_fang=[](int x) { return x*x;};
auto c=my_map(ping_fang,a);//ping_fang是lambda表达式(平方的作用)
cout<<c; long long sum=0;//同理,可以实现这种操作:求前缀和
auto leijia=[=](int x) mutable{ return sum+=x;};
auto d=my_map(leijia,a);
cout<<d;
}

本文作者XXOY

那个input().split(),和cout<<vector可以看我之前的文章

input().split()

cout<<

这次的代码虽然短,但或许确实是(目前)技术含量最高的一篇了。

0.前置芝士:

(1):c++11的新特性(比如auto、lambda)

(2):c++的template(模板)与函数指针

1.首先考虑要实现的功能:

传一个函数与一个vector,返回对vector中每一个元素使用这个函数的新vector。

于是就有了第一版

template<typename T,typename T2>
vector<T2> my_map(T2 (*co)(T),vector<T> yuan){
vector<T2> x;
for(auto i:yuan)
x.push_back(co(i));
return x;
}

传递一个函数指针进去,然后进行操作。

但这样只能搞普通的函数,不能操纵lambda,会报错。

进行了一番百度、google以后发现lambda本质是一个重载过()的类(某种意义上)

于是有了第二版:

template<typename Ori,typename Func_Type>
auto my_map(Func_Type my_func,vector<Ori> &x){
auto k=my_func(yuan[0]);
vector<decltype(k)> tmp;
for(auto i :x)
tmp.push_back(my_func(i));
return tmp;
}

为什么搞一个k呢?因为那时我不知道如何获取一个函数返回值的类型,只能傻傻的先去操作一下先。

会遇到什么问题呢?空的vector会报错。

遂继续百度(这足足花了两天)。

才知道有种东西叫result_of,专门用来获取返回值类型的。

于是--->第三版

template<typename Ori,typename Func_Type>
auto my_map(Func_Type my_func,vector<Ori> &x){
using return_type = typename result_of<Func_Type(Ori)>::type;
vector<return_type> tmp;
for(auto i :x)
tmp.push_back(my_func(i));
return tmp;
}
//result_of 是获取返回值类型的意思。
//可以不需要T2 (*my_func)(T)像这样定义函数,直接把它当一个类用就行了
//对于lambda:某种意义上,它本质上就是一个重载了()的类

OK,写完,收工。

现在,它可以实现如下骚操作。

    auto s=input().split();
//s的类型是vector<string>
cout<<s; auto a=my_map(my_int,s);
//my_int是函数,string转int
//a的类型是vector<int>
cout<<a; //Dao_Shu是一个重载了()的类(结构体)
auto b=my_map(Dao_Shu(),a);
//DS是一个类型为Dao_Shu的变量
//也可以auto b=my_map(DS,a);
//b是vector<double>
cout<<b; auto ping_fang=[](int x) { return x*x;};
//ping_fang是lambda表达式(平方的作用)
auto c=my_map(ping_fang,a);
//c是vector<int>
cout<<c; long long sum=0;
auto leijia=[=](int x) mutable{ return sum+=x;};
//同理,可以实现这种操作:求前缀和
auto d=my_map(leijia,a);
//d是vector<long long>
cout<<d;

完整代码:

#include<bits/stdc++.h>
using namespace std; //split()和input()的实现
struct mystring:string{//继承string类
mystring() :string() {}
mystring& operator=(const string &c) {
(*this).assign(c);
return *this;
}
vector<string> split(char c=' '){
vector<string> x;
int last=0,len=0;
for(int i=0;i<size();++i)
if(at(i)==c){
x.push_back(substr(last,len));
last=i+1;
len=0;
}
else ++len;
if(last<size())
x.push_back(substr(last,len));
return x;
}
}s; mystring input(){
mystring s;
getline(cin,s);
return s;
} //重载cout<<
namespace py_pr{
template<typename T>
inline ostream& out_put(ostream& o,const T & x){
return o<<x;
}
inline ostream& out_put(ostream& o,const string& x){
return o<<"\""<<x<<"\"";
}
inline ostream& out_put(ostream& o,const char* & x){
return o<<"\""<<x<<"\"";
}
inline ostream& out_put(ostream& o,const char & x){
return o<<"\'"<<x<<"\'";
}
template<typename T1,typename T2>
inline ostream& out_put(ostream& o,const pair<T1,T2> & x){
out_put(o,x.first);
o<<": ";
out_put(o,x.second);
return o;
} } template<typename T>
ostream& operator<<(ostream &o,vector<T> &x){
o<<"[";
for(auto i=x.begin();i<x.end();++i){
//可以直接for(auto i:x),但是我不知道怎么特判第一个来控制","
if(i!=x.begin()) o<<", ";
py_pr::out_put(o,*i);
}
o<<"]"<<endl;
return o;
}
template<typename Ori,typename Func_Type>
auto my_map(Func_Type my_func,vector<Ori> &x){
using return_type = typename result_of<Func_Type(Ori)>::type;
vector<return_type> tmp;
for(auto i :x)
tmp.push_back(my_func(i));
return tmp;
}
//result_of 是获取返回值类型的意思。
//可以不需要T2 (*my_func)(T)像这样定义函数,直接把它当一个类用就行了
//对于lambda:某种意义上,它本质上就是一个重载了()的类 int my_int(const string x){
return stoi(x);
} struct Dao_Shu{
double operator() (double x){
return 1.0/x;
}
}DS; int main()
{
auto s=input().split();
//s的类型是vector<string>
cout<<s; auto a=my_map(my_int,s);
//my_int是函数,string转int
//a的类型是vector<int>
cout<<a; //Dao_Shu是一个重载了()的类(结构体)
auto b=my_map(Dao_Shu(),a);
//DS是一个类型为Dao_Shu的变量
//也可以auto b=my_map(DS,a);
//b是vector<double>
cout<<b; auto ping_fang=[](int x) { return x*x;};
//ping_fang是lambda表达式(平方的作用)
auto c=my_map(ping_fang,a);
//c是vector<int>
cout<<c; long long sum=0;
auto leijia=[=](int x) mutable{ return sum+=x;};
//同理,可以实现这种操作:求前缀和
auto d=my_map(leijia,a);
//d是vector<long long>
cout<<d; }

最后的最后Q&A环节:

1.Q:为什么要搞这种东西呢?

A:因为我开心。

2.不能做到的:直接传stoi之类的函数。

原因大概是其中有缺省参数,参数表不匹配。会编译不通过

解决办法:包个壳(感谢@たくやりん 提供的方法)

比如这样int my_int(string x){ return stoi(x); }

更多内容,包括那个input().split(),和cout<<vector可以看我的主页。

input().split()

cout<<

我是XXOY,我们下次再见。

c++实现类似python的map一样,批量操作一个vector的功能【python一样写c++、三】的更多相关文章

  1. 《python解释器源码剖析》第1章--python对象初探

    1.0 序 对象是python中最核心的一个概念,在python的世界中,一切都是对象,整数.字符串.甚至类型.整数类型.字符串类型,都是对象.换句话说,python中面向对象的理念观测的非常彻底,面 ...

  2. python之map、filter、reduce、lambda函数 转

    python之map.filter.reduce.lambda函数  转  http://www.cnblogs.com/kaituorensheng/p/5300340.html 阅读目录 map ...

  3. Python【map、reduce、filter】内置函数使用说明(转载)

    转自:http://www.blogjava.net/vagasnail/articles/301140.html?opt=admin 介绍下Python 中 map,reduce,和filter 内 ...

  4. python基础——map/reduce

    python基础——map/reduce Python内建了map()和reduce()函数. 如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Pro ...

  5. 【转】Python 中map、reduce、filter函数

    转自:http://www.blogjava.net/vagasnail/articles/301140.html?opt=admin 介绍下Python 中 map,reduce,和filter 内 ...

  6. [spark][python]Spark map 处理

    map 就是对一个RDD的各个元素都施加处理,得到一个新的RDD 的过程 [training@localhost ~]$ cat names.txtYear,First Name,County,Sex ...

  7. 使用Python实现Map Reduce程序

    使用Python实现Map Reduce程序 起因 想处理一些较大的文件,单机运行效率太低,多线程也达不到要求,最终采用了集群的处理方式. 详细的讨论可以在v2ex上看一下. 步骤 MapReduce ...

  8. python的map函数的使用方法详解以及使用案例(处理每个元素的自增、自减、平方等)

    1.用我们之前学过的求一下平方(只有一个列表) #求平方 num=[1,5,6,2,7,8] a=[] for n in num: a.append(n**2) print (a) C:\python ...

  9. [译]PYTHON FUNCTIONS - MAP, FILTER, AND REDUCE

    map, filter, and reduce Python提供了几个函数,使得能够进行函数式编程.这些函数都拥有方便的特性,他们可以能够很方便的用python编写. 函数式编程都是关于表达式的.我们 ...

  10. python中map()和dict()的用法

    map()用法 map()是python的内置函数,会根据提供的函数对指定序列做映射. 语法: map(func, iter, ...) 其中func为一个功能函数,iter表示可迭代参数序列.map ...

随机推荐

  1. 暑假学习四 8.26 Hadoop的简单使用

    先说今日情况,本来打算返校结果回不去,然后身体差发烧了,就随便学了一些东西,阑尾炎还是好疼. 有一说一,我觉得我的电脑真的有点拉啊,三台虚拟机开启之后,运存直接90%,呜呜响,和我本人情况一样,麻了 ...

  2. 学习lua-05,io.open 读取输出修改文件,以及io.read的参数运用,读所有,读一行多行

    -- 以附加的方式打开只写文件.若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留.(EOF符保留) file = io.open("D:\\Pr ...

  3. 使用signalr不使用连接服务器和前台的js的方法

    1:使用这种方式,,就不需要前后台链接的js 2:新建一个empty的MVC项目 3:新建一个controller和index.html 4: 新建一个signalr 集线器类名为PersonHub, ...

  4. 机器学习之pandas介绍

    pandas简介 pandas全称python Data Analysis Library,是基于numpy的一种工具,pandas纳入了大量库和一些标准的数据模型,提供了高效的操作大型数据集所需的工 ...

  5. 浏览器F12,Network中各按钮的作用

    Network下 preserve log:勾选,页面发生跳转,接口不丢失:(比如登录成功跳转到首页,登录的接口就没了,勾选Perserve log,会记录跳转前的接口): Disable cache ...

  6. NOI模板复习组——图论部分

    1.最小生成树: kruscal: #include <cstdio> #include <cmath> #include <cstring> #include & ...

  7. centos7 安装 elasticsearch 7.15

    下载 elasticsearch wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linu ...

  8. 消息队列 RocketMQ4.x介绍和新概念讲解

    消息队列 RocketMQ4.x介绍和新概念讲解 Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件 RocketMQ4.x特点 支持Broker和Consumer端消 ...

  9. idea :不支持发行版本11问题

    1.因为我是导入的其他人的项目来进行修改的,所以遇到了这个问题 2. 3. 4.

  10. 禁止的回文子串 Dyslexic Gollum

    UVA1633 一个长的回文串都可以由短的回文串拓展而来,只要短的回文在左右两端增加相同的字符即可.因此,在考虑长度为NNN的01串时,只要在从长度为1向NNN拓展的过程中,保证后KKK个字符不是回文 ...