C++最易读手撸神经网络两隐藏层(任意Nodes每层)梯度下降230821a
// c++神经网络手撸20梯度下降22_230820a.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include<iostream>
#include<vector>
#include<iomanip> // setprecision
#include<sstream> // getline stof()
#include<fstream>
using namespace std;
//
float Loss误差损失之和001 = 0.0;
class NN神经网络NN {
private:
const int inputNode输入层之节点数s, hidden01Node隐藏层01结点数s, hidden22Nodes, outputNode输出层结点数s;
/*
vector<vector<float>> 输入层到第1隐藏层之权重矩阵, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏22到输出层de权重矩阵; //这些变量为矩阵
vector<float> 隐藏层1偏置1, 隐藏层2偏置2, O输出层偏置;
vector<float>隐藏层1数据1, 隐藏层2数据2, 输出数据output; */
void initLayer每一层的WeightsAndBiases(vector<vector<float>>& weights权重, vector<float>& biases偏置)
{
for (size_t i = 0; i < weights权重.size(); ++i) {//for110i
for (size_t j = 0; j < weights权重[0].size(); ++j) { weights权重[i][j] = ((rand() % 2) - 1) / 1.0; }
biases偏置[i] = ((rand() % 2) - 1) / 1.0;
}//for110i
}//void initLayerWeightsAndBiases(
void initWeightsAndBiases初始化权重和偏置矩阵() {
initLayer每一层的WeightsAndBiases(输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1);
initLayer每一层的WeightsAndBiases(隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2);
initLayer每一层的WeightsAndBiases(隐藏22到输出层de权重矩阵 , O输出层偏置);
}
//激活函数-激活的过程
vector<float> activate(const vector<float>& inputs, const vector< vector<float>>& weights, const vector<float>& biases) {
vector<float> layer_output(weights.size(), 0.0);
for (size_t i = 0; i < weights.size(); i++) {
for (size_t j = 0; j < inputs.size(); j++) {
layer_output[i] += inputs[j] * weights[i][j];
}//for220j
layer_output[i] += biases[i];
layer_output[i] = sigmoid(layer_output[i]);
}//for110i
return layer_output;
}//vector<float> activate
//subtract求差:两个 向量的差
vector<float> subtract(const vector<float>& a, const vector<float>& b) {
vector<float> result(a.size(), 0.0);
for (size_t i = 0; i < a.size(); i++) {
result[i] = a[i] - b[i];
}
return result;
}//vector<float>subtract
//dotT点乘
vector<float> dotT(const vector<float>& a, const vector< vector<float>>& b) {
vector<float> result(b[0].size(), 0.0);
for (size_t i = 0; i < b[0].size(); i++) {
for (size_t j = 0; j < a.size(); j++) {
result[i] += a[j] * b[j][i];
}
}
return result;
}
//更新权重矩阵s(们), 和偏置(向量)S们
void updateWeights(const vector<float>& inputs, const vector<float>& errors, const vector<float>& outputs,
vector< vector<float>>& weights, vector<float>& biases, float lr) {
for (size_t i = 0; i < weights.size(); i++) {
for (size_t j = 0; j < weights[0].size(); j++) {
weights[i][j] += lr * errors[i] * sigmoid导函数prime(outputs[i]) * inputs[j];
}
biases[i] += lr * errors[i] * sigmoid导函数prime(outputs[i]);
}
}//void updateWeights(
public:
vector<vector<float>> 输入层到第1隐藏层之权重矩阵, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏22到输出层de权重矩阵; //这些变量为矩阵
vector<float> 隐藏层1偏置1, 隐藏层2偏置2, O输出层偏置;
vector<float>隐藏层1数据1, 隐藏层2数据2, 输出数据output;
NN神经网络NN(int inputNode输入层之节点数s, int hidden01Node隐藏层01结点数s, int hidden22Nodes, int outputNode输出层结点数s)
:inputNode输入层之节点数s(inputNode输入层之节点数s), hidden01Node隐藏层01结点数s(hidden01Node隐藏层01结点数s), hidden22Nodes(hidden22Nodes), outputNode输出层结点数s(outputNode输出层结点数s)
{
srand(time(NULL));
//初始换权重矩阵
输入层到第1隐藏层之权重矩阵.resize(hidden01Node隐藏层01结点数s, vector<float>(inputNode输入层之节点数s));
隐藏层1到第二隐藏层2之权重矩阵1to2.resize(hidden22Nodes, vector<float>(hidden01Node隐藏层01结点数s));
隐藏22到输出层de权重矩阵.resize(outputNode输出层结点数s, vector<float>(hidden22Nodes));//
隐藏层1偏置1.resize(hidden01Node隐藏层01结点数s);
隐藏层2偏置2.resize(hidden22Nodes);
O输出层偏置.resize(outputNode输出层结点数s);
initWeightsAndBiases初始化权重和偏置矩阵();
}//NN神经网络NN(i
//sigmoid激活函数及导数
float sigmoid(float x){ return 1.0 / (1.0 + exp(-x)); }
float sigmoid导函数prime(float x) { return x * (1 - x); }
//Forward前向传播
vector<float> predict(const vector<float>& input输入数据) {
//用激活函数sigmoid-激活的过程
隐藏层1数据1 = activate(input输入数据, 输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1); //激活函数
// 第一隐藏层到第二隐藏层
隐藏层2数据2 = activate(隐藏层1数据1, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2);//hidden1, wh1h2, bias_h2);
// 第二隐藏层到输出层
输出数据output = activate(隐藏层2数据2, 隐藏22到输出层de权重矩阵, O输出层偏置);// , wh2o, bias_o);
return 输出数据output;
}//vector<float>predict(
// 反向传播//Backpropagation
void train(const vector<float>& inputs, const vector<float>& target目标数据s, float lr学习率) {
vector<float> output尝试的输出数据s = predict(inputs);
// 输出层误差
vector<float> output_error输出误差s = subtract(target目标数据s, output尝试的输出数据s);//
Loss误差损失之和001 = 0.0;
for (int ii = 0; ii < outputNode输出层结点数s; ++ii) { Loss误差损失之和001 += fabs(output_error输出误差s[ii]); }
//=========================================================================
// 隐藏层2误差
vector<float> hidden2_errors = dotT(output_error输出误差s, 隐藏22到输出层de权重矩阵);
// 隐藏层1误差
vector<float> hidden1_errors = dotT(hidden2_errors, 隐藏层1到第二隐藏层2之权重矩阵1to2);
// 更新权重: 隐藏层2到输出层(的权重矩阵
updateWeights(隐藏层2数据2, output_error输出误差s, output尝试的输出数据s, 隐藏22到输出层de权重矩阵, O输出层偏置, lr学习率);
// 更新权重: 隐藏层1到隐藏层2
updateWeights(隐藏层1数据1, hidden2_errors, 隐藏层2数据2, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2, lr学习率);
// 更新权重: 输入层到隐藏层1的权重矩阵)
updateWeights(inputs, hidden1_errors, 隐藏层1数据1, 输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1, lr学习率);
}// void train(
// // 反向传播//Backpropagation
};//class NN神经网络NN {
//----------------------------------------------------------------------------------------
void writeVectorToFile(const std::vector<float>& A, const std::string& fileName) {
std::ofstream outFile(fileName);
if (outFile.is_open()) {
for (float value : A) {
outFile << value << std::endl;
}
outFile.close();
}
else {
std::cerr << "Unable to open file for writing: " << fileName << std::endl;
}
}//writeVectorToFile
void readVectorFromFile(std::vector<float>& B, const std::string& fileName) {
std::ifstream inFile(fileName);
float value;
if (inFile.is_open()) {
while (inFile >> value) {
B.push_back(value);
}
inFile.close();
}
else {
std::cerr << "Unable to open file for reading: " << fileName << std::endl;
}
}//readVectorFromFile
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
void writeToFile( const std::vector<std::vector<float>>& A , const std::string& filename) {
std::ofstream file(filename);
if (!file) {
std::cerr << "Error opening file for writing: " << filename << std::endl;
return;
}
for (const auto& row : A) {
for (size_t i = 0; i < row.size(); ++i) {
file << row[i];
if (i != row.size() - 1) {
file << ",";
}
}
file << "\n";
}
file.close();
}//void writeToFile
std::vector<std::vector<float>> readFromFile(const std::string& filename) {
std::vector<std::vector<float>> B;
std::ifstream file(filename);
if (!file) {
std::cerr << "Error opening file for reading: " << filename << std::endl;
return B;
}
std::string line;
while (std::getline(file, line)) {
std::vector<float> row;
std::stringstream ss(line);
std::string value;
while (std::getline(ss, value, ',')) {
row.push_back(std::stof(value));
}
B.push_back(row);
}
file.close();
return B;
}//readFromFile(
//----------------------------------------------------------------------------------------
#define Num训练数据的个数s 4
int main()
{
NN神经网络NN nn(2, 4, 3, 1);// 2, 3, 2, 1);// 11, 10, 4);
// Example
int 训练数据的个数s = Num训练数据的个数s;
vector<float> input[Num训练数据的个数s];
/* input[0] = {0,1,0, 0,1,0, 0,1,0}; //1“竖线”或 “1”字{ 1.0, 0.5, 0.25, 0.125 };
input[1] = { 0,0,0, 1,1,1,0,0,0 }; //-“横线”或 “-”减号{ 1.0, 0.5, 0.25, 0.125 };
input[2] = { 0,1,0, 1,1,1, 0,1,0 }; //+“+”加号{ 1.0, 0.5, 0.25, 0.125 };
input[3] = { 0,1,0, 0,1.2, 0, 0,1, 0 }; // '1'或 '|'字型{ 1.0, 0.5, 0.25, 0.125 };
input[4] = { 1,1,0, 1,0,1.2, 1,1,1 }; //“口”字型+{ 1.0, 0.5, 0.25, 0.125 };
vector<float> target[Num训练数据的个数s];
target[0] = { 1.0, 0,0,0 };// , 0};//1 , 0}; //0.0, 1.0, 0.5}; //{ 0.0, 1.0 };
target[1] = { 0, 1.0 ,0,0 };// , 0};//- 91.0, 0};// , 0, 0}; //
target[2] = { 0,0,1.0,0 };// , 0};//+ 1.0, 0.5};
target[3] = { 1.0 ,0,0, 0.5 };// , 0}; //1
target[4] = { 0,0,0,0 };// , 1.0}; //“口”
*/
vector<float> target[Num训练数据的个数s];
input[0] = { 0,0 }; target[0] = { 0 }; //"-"
input[1] = { 1,0 }; target[1] = { 1 };
input[2] = { 1,1}; target[2] = { 0};
input[3] = { 0,1 }; target[3] = { 1 };
string str0001;
LabeStart001:
//--------------------------------------------------------------------------------------
cout << "1_Trainning;" << endl;
cout << "2_Test;" << endl;
cout << "3_quit." << endl;
getline(cin, str0001);
stringstream s01s001(str0001);
string temp;
getline(s01s001, temp, ',');
int choice = (float)stof(temp); //
switch (choice) {
case 1:
goto LabeTraining;
case 2:
goto LabeTest;
case 3:
return 0;
}
LabeTraining:
for (int i = 0; i < 90000; ++i) {//for110i
for (int jj = 0; jj < Num训练数据的个数s ; ++jj) {
//for (auto& val: input ) {
nn.train(input[jj], target[jj], 0.001);
if (0 ==i % 10000) { std::cout << "[Lost:" << Loss误差损失之和001 << endl; }
}//for220jj
}//for110i
// writeToFile( nn.输入层到第1隐藏层之权重矩阵 , "/file输入层到第1隐藏层之权重矩阵Name220101.txt");
writeToFile(nn.输入层到第1隐藏层之权重矩阵, "/file输入层到第1隐藏层之权重矩阵Name220101.txt");
writeToFile(nn.隐藏22到输出层de权重矩阵, "/file隐藏22到输出层de权重矩阵Name220101.txt");
writeToFile(nn.隐藏层1到第二隐藏层2之权重矩阵1to2, "/file隐藏层1到第二隐藏层2之权重矩阵1to2Name220101.txt");
writeVectorToFile( nn.隐藏层1偏置1, "/file隐藏层1偏置1.txt");
writeVectorToFile(nn.隐藏层2偏置2, "/file隐藏层2偏置2.txt");
writeVectorToFile(nn.O输出层偏置, "/fileO输出层偏置.txt");
std::cout << endl;
LabeTest:
//--------------------------------------
input[1] = { 0,1 };// 0, 0, 1, 1, 0.98, 0, 0, 0}; //1/
vector<float> outpu输出数据001t = nn.predict(input[0]);
for (auto& val : outpu输出数据001t)
std::cout << fixed << setprecision(9) << val << " ";
std::cout << endl;
//-------------------------------------------------------------
// do {
std::cout << endl << "请输入一个字符串(要求字符串是包含9个由逗号分隔的数字的字符串,如 1,2,0,0,5,0,0,8,9等): " << endl;
getline( cin, str0001);
stringstream
s01s002(str0001);
for (int i = 0; i < 2;++i) {//
//9; ++i) {
string temp;
getline(s01s002, temp, ',');
input[1][i] = (float) stof(temp); // 将字符串转化为整数
}
std::cout << "数字数组为: ";
for (int i = 0; i < 2;++i) {// 9; ++i) {
std::cout << input[1][i] << " ";
}
//
readVectorFromFile(nn.隐藏层1偏置1, "/file隐藏层1偏置1.txt");
readVectorFromFile(nn.隐藏层2偏置2, "/file隐藏层2偏置2.txt");
readVectorFromFile(nn.O输出层偏置, "/fileO输出层偏置.txt");
nn.输入层到第1隐藏层之权重矩阵 = readFromFile("/file输入层到第1隐藏层之权重矩阵Name220101.txt");
nn.隐藏层1到第二隐藏层2之权重矩阵1to2 = readFromFile("/file隐藏层1到第二隐藏层2之权重矩阵1to2Name220101.txt");
nn.隐藏22到输出层de权重矩阵 = readFromFile("/file隐藏22到输出层de权重矩阵Name220101.txt");
//
outpu输出数据001t = nn.predict(input[1]);
std::cout << endl;
for (auto& val : outpu输出数据001t)
std::cout << fixed << setprecision(9) << val << " ";
cout << endl;
// } while (true);// 1 == 1);
//======================================
std::cout << "Hello World!请继续……您可以继续训练网络,或者测试网络!\n";
goto LabeStart001;
}//main
相关文章:
C++最易读手撸神经网络两隐藏层(任意Nodes每层)梯度下降230821a
// c神经网络手撸20梯度下降22_230820a.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 #include<iostream> #include<vector> #include<iomanip> // setprecision #include<sstream> // getline stof() #include<fstream…...
Leetcode 2235.两整数相加
一、两整数相加 给你两个整数 num1 和 num2,返回这两个整数的和。 示例 1: 输入:num1 12, num2 5 输出:17 解释:num1 是 12,num2 是 5 ,它们的和是 12 5 17 ,因此返回 17 。示例…...
Postman —— postman实现参数化
什么时候会用到参数化 比如:一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块:正确的用户名,密码 成功;错误的用户名,正确的密码 失败 postman实现参数化 在实际的接口测试中,部分参数每…...
LeetCode--HOT100题(41)
目录 题目描述:102. 二叉树的层序遍历(中等)题目接口解题思路代码 PS: 题目描述:102. 二叉树的层序遍历(中等) 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地&am…...
微信小程序教学系列(6)
第六章:小程序商业化 第一节:小程序的商业模式 在这一节中,我们将探讨微信小程序的商业模式,让你了解如何将你的小程序变成一个赚钱的机器! 1. 广告收入 小程序的商业模式之一是通过广告收入赚钱。你可以在小程序中…...
小程序中的全局配置以及常用的配置项(window,tabBar)
全局配置文件和常用的配置项 app.json: pages:是一个数组,用于记录当前小程序所有页面的存放路径,可以通过它来创建页面 window:全局设置小程序窗口的外观(导航栏,背景,页面的主体) tabBar:设置小程序底部的 tabBar效果 style:是否…...
数据工厂调研及结果展示
数据工厂 一、背景 在开发自测、测试迭代测试、产品验收的过程中,都需要各种各样的前置数据,大致分为如下几类: 账号(实名、权益等级、注册等) 货源(优货、急走、相似、一手、普通货源等) …...
抓包相关,抓包学习
检查网络流量 - 提琴手经典 (telerik.com) Headers Reference - Fiddler Classic (telerik.com) 以上是fiddler官方文档 F12要勾选保留日志 不勾选的话跳转到新页面之前页面的日志不会在下方显示 会保留所有抓到的包 如果重定向到别的页面 F12抓包可能看不到响应信息,但是…...
云原生之使用Docker部署SSCMS内容管理系统
云原生之使用Docker部署SSCMS内容管理系统 一、SSCMS介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载SSCMS镜像五、部署SSCMS内容管理系统5.1 创建SSCMS容器5.2 检查SSC…...
uniapp -- 在组件中拿到pages.json下pages设置navigationBarTitleText这个值?
1:在 pages.json 文件中设置 navigationBarTitleText,例如: {"pages": [{"path": "pages/home/index","style": {"navigationBarTitleText": "首页",&...
Java获取环境变量和运行时环境信息和自定义配置信息
System.getenv() 获取系统环境变量 public static void main1() {Map<String, String> envMap System.getenv();envMap.entrySet().forEach(x-> System.out.println(x.getKey() "" x.getValue())); } System.getenv() 获取的是操作系统环境变量列表&…...
React入门 组件学习笔记
项目页面以组件形式层层搭起来,组件提高复用性,可维护性 目录 一、函数组件 二、类组件 三、 组件的事件绑定 四、获取事件对象 五、事件绑定传递额外参数 六、组件状态 初始化状态 读取状态 修改状态 七、组件-状态修改counter案例 八、this问…...
Windows商店引入SUSE Linux Enterprise Server和openSUSE Leap
在上个月的Build 2017开发者大会上,微软宣布将SUSE,Ubuntu和Fedora引入Windows 商店,反应出微软对开放源码社区的更多承诺。 该公司去年以铂金会员身份加入Linux基金会。现在,微软针对内测者的Windows商店已经开始提供 部分Linux发…...
[NLP]深入理解 Megatron-LM
一. 导读 NVIDIA Megatron-LM 是一个基于 PyTorch 的分布式训练框架,用来训练基于Transformer的大型语言模型。Megatron-LM 综合应用了数据并行(Data Parallelism),张量并行(Tensor Parallelism)和流水线并…...
软考高级系统架构设计师系列论文七十八:论软件产品线技术
软考高级系统架构设计师系列论文七十八:论软件产品线技术 一、摘要二、正文三、总结一、摘要 本人作为某软件公司负责人之一,通过对位于几个省的国家甲级、乙级、丙级设计院的考查和了解,我决定采用软件产品线方式开发系列《设计院信息管理平台》产品。该产品线开发主要有如…...
yolov5中添加ShuffleAttention注意力机制
ShuffleAttention注意力机制简介 关于ShuffleAttention注意力机制的原理这里不再详细解释.论文参考如下链接here yolov5中添加注意力机制 注意力机制分为接收通道数和不接受通道数两种。这次属于接受通道数注意力机制,这种注意力机制由于有通道数要求,所示我们添加的时候…...
Effective C++条款17——以独立语句将newed 对象置入智能指针(资源管理)
假设我们有个函数用来揭示处理程序的优先权,另一个函数用来在某动态分配所得的widget上进行某些带有优先权的处理: void priority(); void processWidget(std::tr1::shared_ptr<Widget>pw, int priority);由于谨记“以对象管理资源”(条款13&…...
奇迹MU服务器如何选择配置?奇迹MU服务器租用
不同的服务器,根据其特点与性能适用于不同的应用场景,为了让你们更好的理解,我们对服务器进行了分类归纳,结合了服务器不同的特点以及价位进行一个区分,帮助我们更好的选择合适的服务器配置。 VPS服务器 VPS服务器又…...
如何远程管理服务器详解
文章目录 前言一、远程管理类型二、远程桌面三、telnet 命令行远程四、查看本地开放端口 前言 很多公司是有自己的机房的,机房里面会有若干个服务器为员工和用户提供服务。大家可以想想:假设这家公司有上百台服务器,我们作为网络工程师&…...
JavaScript——为什么静态方法不能调用非静态方法
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
