Эффективное подмножество std :: vector <double> - PullRequest
0 голосов
/ 14 сентября 2018

Предположим, что у нас есть набор двойных чисел в std::vector<double>. Давайте назовем это data. Теперь я хочу создать новый std :: vector, который состоит из (упорядоченного) подмножества data с помощью метода subvector, например. пусть data = [0,4,3,5,5,7] и я хочу метод, который дает мне

std::vector<int> indices(3);
indices[0] = 1;
indices[1] = 2;
indices[2] = 4;
std::vector<double> subdata = data.subvector(indices);

и результат должен быть subdata = [4,3,5]. Конечно, я могу добиться этого, просто скопировав значения data, но что я действительно хочу, так это то, что если я изменю значения в subdata, они также изменятся в data, т.е. если я сделаю subdata[2]=-1, то хочу это data = [0,4,3,5,-1,7].

Итак, я должен сделать что-то вроде «запоминания» указателя в data. Я пробовал несколько вариантов с указанием & и * здесь и там, но я не смог получить желаемый результат.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Хранить указатели на элементы немного опасно, потому что внутренний буфер вектора может быть заменен (автоматически) при добавлении элементов, и тогда эти указатели будут зависать.

Но вы можете сохранить указатель или ссылку на сам вектор, например так:

#include <vector>
#include <initializer_list>
using namespace std;

class Subdata
{
    vector<int>&        m_data;
    const vector<int>   m_indices;

public:
    auto operator[]( const int i )
        -> int&
    { return m_data[m_indices[i]]; }

    Subdata( vector<int>&  data, const initializer_list<int>& indices ):
        m_data( data ),
        m_indices( indices.begin(), indices.end() )
    {}
};

#include <iostream>
auto main()
    -> int
{
    vector<int> data = {0, 4, 3, 5, 5, 7};
    Subdata subdata( data, {1, 2, 4} );
    subdata[2] = -1;
    for( const int v : data ) { cout << v << ' '; } cout << endl;
}
0 голосов
/ 14 сентября 2018

что я действительно хочу, так это то, что если я изменяю значения в подданных, они также изменяются в данных, т.е. если я subdata[2]=-1 хочу, чтобы data = [0,4,3,5,-1,7].

Для этого вам необходимо сохранить указатели для членов в data. Это могут быть необработанные указатели (int*) или итераторы (std::vector<int>::iterator).

Однако хранение указателей рискованно. Они могут быть признаны недействительными путем изменений в data. Более безопасный способ - просто использовать индексы и получать / устанавливать значения элементов data, используя индексы.

data[indices[0]] = <some value>; // Set the value in data
int x = data[indices[1]];        // Get the value from data

Поскольку std::vector является контейнером произвольного доступа, стоимость доступа к элементам data не повлияет на производительность, если это вызывает озабоченность.

...