#c #object-slicing
#c #нарезка объектов
Вопрос:
У меня есть C-массив, подобный этому:
int X[]={0, 1, 2, 3, 4, 5, 6, 7, 8};
Мне нужно создать два stl-вектора из этого массива с помощью нарезки, возможно, с использованием наибольшего объема памяти и с возможностью создания менее глубоких копий.
Первый вектор Y должен содержать только 0
-й и первый элемент каждые три элемента, например, в этом случае этот новый вектор Y
будет содержать
std::vector<int> Y; // contains: [0,1,3,4,6,7]
и другой вектор Z должен содержать каждый 3-й элемент в исходном массиве:
std::vector<int> Z; // contains [2,5,8]
Первое решение, основанное на циклах for с copy , заключается в следующем:
vector<int> Y,Z;
for (int i=0; i<9;i =3)
{
Y.push_back(*(X i));
Y.push_back(*(X i 1));
Z.push_back(*(X 2));
}
но я почти уверен, что с помощью пользовательских итераторов проблема может иметь более эффективное решение. Есть ли, в любом случае, какая-то другая более быстрая версия реализации представления маски в этом массиве, которая позволяет избежать создания копий?
Комментарии:
1. Какие-либо конкретные вопросы?
2. Я не думаю, что есть способ сделать это с помощью пользовательских итераторов без чрезмерной инженерии.
3. Я не понимаю, как пользовательские итераторы могли бы сделать ваш простой цикл for более «эффективным» (хотя вы могли бы использовать некоторые
.reserve
s) en.wikipedia.org/wiki/KISS_principle4. Кроме использования
reserve()
, я сомневаюсь, что вы могли бы добиться гораздо большей эффективности.5. @LightnessRacesinOrbit: разве «Упростить, а затем добавить легкости» не подходит вам лучше 🙂
Ответ №1:
Может быть, вы имеете в виду что-то вроде этого:
#include <iostream>
#include <vector>
using namespace std;
struct MyIndexing {
int* original;
MyIndexing(int* o) : original(o) {}
intamp; getY(int index){ return original[0]; /* to be done... */ }
intamp; getZ(int index){ return original[(index 1)*3 -1]; }
};
int main() {
int X[]={0, 1, 2, 3, 4, 5, 6, 7, 8};
MyIndexing mi(X);
for (int i=0;i<3;i ){ std::cout << mi.getZ(i) << " "; }
return 0;
}
С принтами:
2 5 8
Он не создает векторы, но в любом случае ваши требования немного противоречат друг другу. Либо вы избегаете копий, либо создаете новые векторы. Оба варианта невозможны.
Ответ №2:
Если вам НУЖНО создавать векторы, вы ДОЛЖНЫ сделать копию данных, поскольку данные векторов являются непрерывными.
Если вам не нужны векторы, вы могли бы создать 2 интерфейса (простите мою терминологию C #, но я думаю, что это применимо), один, который обеспечивал бы получение данных Y, другой, который предлагал бы данные X; реализация, расширяющая эти 2 интерфейса, может скрыть тот факт, что вашданные вообще находятся в векторе.
Комментарии:
1. Все фактически верно. Однако такой интерфейс был бы довольно неэффективным для использования в большинстве сценариев, которые я себе представляю. Тем не менее, похоже, что это то, что запрашивает OP (сейчас), после редактирования. Однако вы на самом деле не предоставили решения