简体   繁体   English

C ++从数组中获取前n个元素

[英]C++ take first n elements from array

Using C++, I want to create an array which only contains the first n elements of another array.使用 C++,我想创建一个仅包含另一个数组的前 n 个元素的数组。 Like so in Scala: val arrayTwo = arrayOne.take(n)就像在 Scala 中一样: val arrayTwo = arrayOne.take(n)

I know I can use a loop and copy the elements one by one, but this is much more complicated than necessary, it takes unnecessary space, and that makes it less readable.我知道我可以使用循环并一个一个地复制元素,但这比必要的复杂得多,它占用了不必要的空间,这使得它的可读性降低。 Is there a simple, readable function to create a new array from the first n elements of a given previous array?是否有一个简单易读的函数来从给定的先前数组的前 n 个元素创建一个新数组? Also I would like to reuse a function from somewhere, rather than writing one on my own, because I don't want to pollute the namespace unnecessarily.此外,我想从某个地方重用一个函数,而不是自己编写一个函数,因为我不想不必要地污染命名空间。 Performance doesn't matter as long as it takes O(n).只要花费 O(n),性能就无关紧要。

std::copy_n looked like it, but I can't get it to work because std::back_inserter for some reason doesn't accept my array (I also tried with a pointer instead of array, still not working). std::copy_n 看起来像它,但我无法让它工作,因为 std::back_inserter 出于某种原因不接受我的数组(我也尝试使用指针而不是数组,但仍然无法工作)。

This is my best attempt so far.这是我迄今为止最好的尝试。

#include <iostream>
#include <utility>
#include <algorithm>
#include <vector>
#include <iterator>
#include <stdio.h>
#include <math.h>

using std::pair;

int main() {
  pair<double, double> fabricatedPoints[] = { { 15.3, 12.9 }, { 88.6, 56.0 },
            { 0.4, 18.0 }, { 5.0, 3.13 }, { 2.46, 86.01 } };
  pair<double, double> points[] = {};
  std::copy_n(std::begin(fabricatedPoints), 3, std::back_inserter(points));
}

It can be done either with copy_n, or by other means, I don't mind as long as it is readable.可以使用 copy_n 或通过其他方式完成,只要它是可读的,我不介意。 If there exists no readable solution in libraries (not necessarily the standard libraries - it could also be Boost or something, as long as it's a widely used library), then I will accept an answer which provides convincing evidence of no such solution existing.如果库中不存在可读的解决方案(不一定是标准库 - 它也可以是 Boost 或其他东西,只要它是一个广泛使用的库),那么我将接受一个答案,该答案提供了不存在此类解决方案的令人信服的证据。

If you were using vectors (and you should, you're using C++), you could just do this:如果你使用向量(你应该使用 C++),你可以这样做:

using std::vector;
vector<pair<double, double>> a{ {15.3, 12.9}, ...};
vector<pair<double, double>> b(a.begin(), a.begin() + 3);

For arrays you will have to make sure to preallocate the array to the right size:对于数组,您必须确保将数组预分配到正确的大小:

pair<double, double> b[3];
std::copy_n(a, 3, b);

You can't append to normal C-style arrays like points (actually, I would be surprised if the declaration didn't generate compiler errors).您不能附加到像points这样的普通 C 样式数组(实际上,如果声明没有产生编译器错误,我会感到惊讶)。 Trying to append to a C-style array would write beyond the bounds, leading to undefined behavior (and here too I'm surprised that std::back_inserter would compile when passed a C-style array).尝试追加到 C 风格的数组会超出界限,导致未定义的行为(在这里我也很惊讶std::back_inserter在传递 C 风格的数组时会编译)。

Instead use a std::vector .而是使用std::vector

I would use vector for this我会为此使用vector

vector<int> vec1;
vector<int> vec2;
vector<int> merged;

//insert(where you want to start adding, from which index, to which index)
//in this case we are adding the first to n-th elements from vec1 to the last element of merged 
merged.insert(merged.end(), vec1.begin(), vec1.begin() + n);

//here we are adding the m-th to n-th elements of vec2 to the first element of merged
merged.insert(merged.begin(), vec2.begin() + m, vec2.begin() + n);

From C++20 ranges ( #include <ranges> )从 C++20 范围( #include <ranges>

Simply use take_view只需使用take_view

//DATA
std::pair<double, double> fabricatedPoints[] = { { 15.3, 12.9 }, { 88.6, 56.0 },
    { 0.4, 18.0 }, { 5.0, 3.13 }, { 2.46, 86.01 } };

//USE take_view
auto points = std::ranges::take_view(fabricatedPoints, 2);

//TEST THEM
for (auto p : points)
{
     std::cout << p.first << "  " << p.second << std::endl;;
}

Or using view adapters或者使用视图适配器

//YOUR DATA
std::pair<double, double> fabricatedPoints[] = { { 15.3, 12.9 }, { 88.6, 56.0 },
        { 0.4, 18.0 }, { 5.0, 3.13 }, { 2.46, 86.01 } };

//GET FIRST TWO POINTS
auto points = std::views::all(fabricatedPoints) | std::views::take(2);

//TEST THEM
for (auto p : points)
{
    std::cout << p.first << "  " << p.second << std::endl;;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM