寻求优雅算法实现节点值设置及vector子范围移除方案
问题描述
我有一个存储bool值的std::vector<bool>,还有若干固定大小的节点容器(_inputNodes、_hiddenNodes、_outputNodes),BrainNode类结构如下:
std::vector<BrainNode> _inputNodes; std::vector<std::vector<BrainNode>> _hiddenNodes; std::vector<BrainNode> _outputNodes; class BrainNode { float _value{ 0 }; std::vector<bool> connections; public: bool operator[](size_t index); };
我需要遍历这个大的bool容器,将其中的值赋值给节点内的connections容器,同时希望用更优雅的算法(比如带谓词的std::copy或范围移动算法)移除已使用的子范围。目前的实现代码如下:
std::vector<bool> gaia::NeuralNet::set_input_nodes(std::vector<bool> nodeConactions) { uint i = 0; for (BrainNode& node : _inputNodes) { node[nodeConactions[i++]]; } auto it = std::rotate(nodeConactions.begin(), nodeConactions.begin()+i, nodeConactions.end()); nodeConactions.erase(it); return nodeConactions; }
想寻求更简洁的实现,类似直接通过算法结合erase移除已使用范围的逻辑。
优化实现方案
方案1:移除冗余的std::rotate,直接删除已使用元素
你当前代码里的std::rotate是多余的——它的作用是把已使用的前i个元素移到容器末尾,再删除末尾元素。但直接删除容器开头的i个元素,就能得到完全相同的剩余元素,代码更简洁高效:
std::vector<bool> gaia::NeuralNet::set_input_nodes(std::vector<bool> nodeConnections) { const auto nodeCount = _inputNodes.size(); // 可选:添加参数合法性检查,避免越界 if (nodeConnections.size() < nodeCount) { return nodeConnections; } size_t idx = 0; for (BrainNode& node : _inputNodes) { // 假设operator[]返回可赋值的引用,若逻辑是向connections添加元素,需调整写法 node[nodeConnections[idx++]]; } // 直接删除已使用的前nodeCount个元素 nodeConnections.erase(nodeConnections.begin(), nodeConnections.begin() + nodeCount); return nodeConnections; }
方案2:结合标准算法完成赋值+移动元素
如果希望用标准算法替代手动循环,同时利用移动语义减少拷贝开销(针对vector<bool>的比特容器也适用),可以用std::for_each配合lambda实现:
std::vector<bool> gaia::NeuralNet::set_input_nodes(std::vector<bool> nodeConnections) { const auto nodeCount = _inputNodes.size(); if (nodeConnections.size() < nodeCount) { return nodeConnections; } size_t idx = 0; std::for_each(_inputNodes.begin(), _inputNodes.end(), [&nodeConnections, &idx](BrainNode& node) { // 若需求是转移元素而非拷贝,可改用移动语义 // node.connections.push_back(std::move(nodeConnections[idx])); node[nodeConnections[idx++]]; }); nodeConnections.erase(nodeConnections.begin(), nodeConnections.begin() + nodeCount); return nodeConnections; }
关键说明
- 移除
std::rotate的原因:它会额外移动容器内的元素,增加不必要的性能开销,直接删除开头的已使用元素逻辑更直观,效率更高。 - 移动语义的使用:如果你的需求是将
nodeConnections中的元素转移到节点的connections中(而非拷贝),可以用std::move(nodeConnections[idx])替代直接访问,减少内存操作。 - 合法性检查:建议添加元素数量校验,避免数组越界访问。
内容的提问来源于stack exchange,提问作者Isak True
相关产品推荐
相关产品推荐

