我有一个来源std::vector<double>
,我想根据std::vector<int>
中包含的索引进行拆分。拆分包括在内,下一个切片的起点应从源矢量的起点开始,在上一个中断的起点开始。
例如:
{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 } -> source
{2, 4, 7 } -> split indices
,应用该功能后,应产生:
{1.1, 2.2, 3.3}
{4.4, 5.5}
{6.6, 7.7, 8.8}
我有这个不会给我第三个向量,依此类推:
vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
vector<int> ends{2, 4, 7 };
vector<vector<double>> periodnumbers;
vector<double> numbers;
for (int i = 0; i < nets.size(); i++)
{
double temp;
temp = nets[i];
numbers.push_back(temp);
for (int j = 0; j < ends.size(); j++)
{
if (i == ends[j])
{
periodnumbers.push_back(numbers);
numbers.clear();
}
}
}
答案 0 :(得分:1)
if(i == ends[i])
一个选择是使用另一个变量。
vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
vector<int> ends{2, 4, 7};
vector<vector<double>> periodnumbers;
vector<double> numbers;
int j=0;
for (int i = 0; i < nets.size(); i++)
{
double temp;
temp = nets[i];
numbers.push_back(temp);
//cout<<numbers[i]<<endl;
if (i == ends[j])
{
//cout<<i<<" "<<nets[i]<<endl;
periodnumbers.push_back(numbers);
numbers.clear();
j++;
//break;
}
//cout<<numbers[i]<<endl;
}
cout<<"Size"<<periodnumbers.size()<<endl;
for(int i=0;i<periodnumbers.size();i++){
for(int j=0;j<periodnumbers[i].size();j++){
cout<<periodnumbers[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
答案 1 :(得分:1)
即使成功,它也会执行过多不必要的操作。从循环所有元素开始,以push_back
结束,而不是保留/调整大小。
让我们假设ends
已排序。然后,一个人只能拿两个“滑块”,然后继续移动它们。左滑块从源矢量的开始处开始,右滑块从第一端开始。随着算法的进行,它将在滑块内部复制当前范围,将左侧滑块移至右侧滑块,而右侧滑块成为下一个端点。
#include <vector>
#include <algorithm>
std::vector<std::vector<double>> split_ends(const std::vector<double>& source, const std::vector<int>& ends) {
std::vector<std::vector<double>> result;
result.reserve(ends.size());
auto anchor_front = source.begin();
for (auto one_end: ends) {
auto anchor_end = std::next(source.begin(), one_end + 1);
result.emplace_back(anchor_front, anchor_end);
anchor_front = anchor_end;
}
return result;
}
#include <iostream>
void print(const std::vector<double>& v)
{
for (auto x: v) {
std::cout << x << ' ';
}
}
int main() {
std::vector<double> nets{1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
std::vector<int> ends{2, 4, 7};
auto splitted = split_ends(nets, ends);
for (const auto& v: splitted) {
print(v);
std::cout << '\n';
}
}
输出:
1.1 2.2 3.3
4.4 5.5
6.6 7.7 8.8
上面的算法假定ends
已排序,并且不包含超出范围的索引。如果不需要副本,则可以保存端点迭代器,然后直接在源上执行更改。
答案 2 :(得分:0)
我不确定您是否考虑过很多细节。我的答案可以调整。
尤其是,我希望cores <- c("Average", "Core1", "Core2", "Core5")
Free <- c(65, 60, 80,50)
Used <- c(100-65, 40, 20,50)
data <- data.frame(cores, Free, Used)
plot_ly(data, x = ~cores, y = ~Used, type = 'bar', name = 'Used') %>%
add_trace(y = ~Free, name = 'Free') %>%
layout(yaxis = list(title = '%'), barmode = 'stack')
为0。
WEIRD_OFFSET
这将产生:
#include <cassert>
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
const bool ONLY = true;
const bool BEFORE_FIRST = true;
const bool AFTER_LAST = true;
const bool ALLOW_EMPTY = true;
const size_t WEIRD_OFFSET = 1;
template<class T>
vector<vector<T>> frob(const vector<T>& nets, const vector<int>& ends)
{
vector<vector<T>> rv;
if (ends.empty())
{
if (ONLY)
{
if (ALLOW_EMPTY || !nets.empty())
rv.push_back(nets);
}
}
else
{
if (BEFORE_FIRST)
{
auto bi = 0;
auto ei = ends[0] + WEIRD_OFFSET;
assert (0 <= bi && bi <= ei && ei <= nets.size());
auto b = nets.begin() + bi;
auto e = nets.begin() + ei;
if (ALLOW_EMPTY || b != e)
rv.push_back(vector<T>(b, e));
}
for (size_t i = 0; i < ends.size() - 1; ++i)
{
auto bi = ends[i] + WEIRD_OFFSET;
auto ei = ends[i+1] + WEIRD_OFFSET;
assert (0 <= bi && bi <= ei && ei <= nets.size());
auto b = nets.begin() + bi;
auto e = nets.begin() + ei;
if (ALLOW_EMPTY || b != e)
rv.push_back(vector<T>(b, e));
}
if (AFTER_LAST)
{
auto bi = ends.back() + WEIRD_OFFSET;
auto ei = nets.size();
assert (0 <= bi && bi <= ei && ei <= nets.size());
auto b = nets.begin() + bi;
auto e = nets.begin() + ei;
if (ALLOW_EMPTY || b != e)
rv.push_back(vector<T>(b, e));
}
}
return rv;
}
int main()
{
vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
vector<int> ends{2, 4, 7};
vector<vector<double>> periodnumbers = frob(nets, ends);
for (const auto& v : periodnumbers)
{
for (const auto& i : v)
{
cout << i << ' ';
}
cout << '\n';
}
cout << std::flush;
}
答案 3 :(得分:0)
如果我们可以假设df.index
是按升序排序的,并且ends
中的值永远不会大于ends
允许的大小,那么这很简单可以给您想要的结果的功能:
nets
包含示例数据的整个程序如下所示:
template<typename T>
std::vector<std::vector<T>> split(const std::vector<T>& nets, const std::vector<int>& ends)
{
std::vector<std::vector<T>> result;
int previous_offset = 0;
for (int i : ends)
{
const std::vector<T> piece(nets.begin() + previous_offset, nets.begin() + i + 1);
previous_offset = i;
result.push_back(piece);
}
return result;
}
输出将是:
#include <iostream>
#include <vector>
// function from above
template<typename T>
std::vector<std::vector<T>> split(const std::vector<T>& nets, const std::vector<int>& ends)
{
std::vector<std::vector<T>> result;
int previous_offset = 0;
for (int i : ends)
{
const std::vector<T> piece(nets.begin() + previous_offset, nets.begin() + i + 1);
previous_offset = i;
result.push_back(piece);
}
return result;
}
int main()
{
// input data
std::vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
std::vector<int> ends{2, 4, 7 };
// variable that will hold the result
std::vector<std::vector<double>> periodnumbers;
// This is where the work happens.
periodnumbers = split(nets, ends);
// Write result to standard output.
std::cout << "There are " << static_cast<int>(periodnumbers.size()) << " pieces:" << std::endl;
for (auto vec : periodnumbers)
{
std::cout << "Next piece is: ";
for (auto elem: vec)
{
std::cout << elem << " ";
}
std::cout << std::endl;
}
return 0;
}
答案 4 :(得分:0)
我提出了以下代码,它们更简单易懂
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
vector<int> ends{2, 4, 7 };
ends.push_back(nets.size()-1);
vector<vector<double>> periodnumbers;
vector<double> numbers;
int j=0;
int coming_split_index=ends[j];
for (int i = 0; i < nets.size(); i++){
if(i<=coming_split_index){
numbers.push_back(nets[i]);
}else{
j++;
coming_split_index=ends[j];
periodnumbers.push_back(numbers);
numbers.clear();
i--;
/*when the index i reaches the coming index the corresponding
*value won't be added to any subvector because It will skip the
*pervious instruction for this reason I decrement the counter i so
*that it repeats it and the next time the one in the previous will
*be executed
*/
}
}
这将显示您的结果
1.1 2.2 3.3
4.4 5.5
6.6 7.7 8.8