Форум программистов, компьютерный форум CyberForum.ru

Массив-ссылка на некоторые элементы другого массива - C++

Восстановить пароль Регистрация
 
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 16:43     Массив-ссылка на некоторые элементы другого массива #1
У меня тут возникла идея. Есть большой двумерный массив, но не все строки этой матрицы нам нужны. Индексы нужных строк записаны в другой массив.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//большая матрица
int a[nRows][nCols];
 
//нужные индексы
int index[numInd];
 
//тут неверно, так как объявили без присваивания
int& b[numInd][nCols];
 
//и эту матрицу связать с определенными элементами матрицы a 
for (int j = 0; j < numInd; j++)
   for (int i = 0; i < nCols; i++)
       // тут тоже вроде неверно. просто излагаю идею
       b[j][i] = a[index[j]][i];
Это я буду делать для того, чтобы отправлять другому процессору матрицу b целиком <т.е. выборку их матрицы а>
что то вроде
C++
1
mpi_send(destination = destination_proc, tag = tag, type = mpi_int, numElements = numInd*nCols, dataToSend = b);
можно, конечно, сделать массив и просто копировать туда каждый раз, но когда количество итераций порадка ~ 1 000 000, операция копирования создает лишний дискомфорт.

Собственно вопрос: как по хорошему реализовать такую матрицу?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2013, 16:43     Массив-ссылка на некоторые элементы другого массива
Посмотрите здесь:

одномерный массив. Все его элементы, не равные нулю, переписать, сохраняя их порядок в начало массива, а нулевые элементы в конец массива in c++ C++
Есть два потока и глобальный массив, могут ли потоки перепутать элементы глобального массива или другого контейнера? C++
Ввод в массив элементы другого массива. C++
C++ Массив: Сформировать третий массив, в который включить все отрицательные элементы массива А и все максимальные элементы массива В.
Вывести некоторые элементы массива в двоичный файл C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 16:58     Массив-ссылка на некоторые элементы другого массива #2
C++
1
2
3
int **a=new int[nRowns];
for( int i=0;i<nRows;++i)
    *a[i]=new int [nCols];
как-то так. а потом на новый массив цеплять уже готовые строки, с помощью указателей
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 17:01  [ТС]     Массив-ссылка на некоторые элементы другого массива #3
Цитата Сообщение от metaluga145 Посмотреть сообщение
C++
1
2
3
int **a=new int[nRowns];
for( int i=0;i<nRows;++i)
    *a[i]=new int [nCols];
как-то так. а потом на новый массив цеплять уже готовые строки, с помощью указателей
Идея хорошая, но ввиду работы с boost serialization надо стараться избегать работать с указателями и все-таки попробовать через ссылки.
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:14     Массив-ссылка на некоторые элементы другого массива #4
Цитата Сообщение от sl_k Посмотреть сообщение
ввиду работы с boost serialization надо стараться избегать работать с указателями и все-таки попробовать через ссылки.
Почему?

Добавлено через 7 минут
пока не вижу никаких препятствий использовать указатели
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 17:22  [ТС]     Массив-ссылка на некоторые элементы другого массива #5
Цитата Сообщение от metaluga145 Посмотреть сообщение
Почему?
на самом деле у меня не двумерный массив а элемент типа
C++
1
class Matrix;
со всеми вытекающими отсюда операторами работы с матрицой.

Потом есть вектор, состоящий из этих матиц

C++
1
mymath::Vector<Matrix> a(nMatrix);

Если я сделаю что то вроде вектора, который состоит из ссылок на матрицы из другого вектора
C++
1
mymath::Vector<Matrix*> b(nMatrix);
то в классе Matrix нужно прописывать функции, которые восстанавливают указатели, если их передавать.
(save_costruct_data и load_construct_data, если вы знакомы с boost serialization)

Поэтому, я бы хотел, чтобы можно было только "копировать" нужные элементы (объекты) по ссылке, но не заморачиваться указателями и выпадающими для них функциями с save_construct_data и load_construct_data

Добавлено через 5 минут
Если, конечно, ничего не решится в ссылками, тогда придется раздувать классы и писать через указатели
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:39     Массив-ссылка на некоторые элементы другого массива #6
Я не сильно с библиотеками boost знаком, но попробую разобраться.
Вы используете свой класс матриц?
мне кажется,что этот вопрос лучше перенести в раздел boost c++
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 17:54  [ТС]     Массив-ссылка на некоторые элементы другого массива #7
Цитата Сообщение от metaluga145 Посмотреть сообщение
Вы используете свой класс матриц?
Да, класс матриц свой.

Цитата Сообщение от metaluga145 Посмотреть сообщение
мне кажется,что этот вопрос лучше перенести в раздел boost c++
Ну так как вопрос не совсем про сам буст и как его использовать, а скорее "можно ли сделать матрицу ссылок в с++?", то делать этому вопросу в boost c++ нечего, по-моему)
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:59     Массив-ссылка на некоторые элементы другого массива #8
Цитата Сообщение от sl_k Посмотреть сообщение
Да, класс матриц свой.
Раз уж Вы пользуетесь boost, то используйте уже и их класс матриц, а еще лучше и их вектор. Думаю,если совместить это всем, то там уже все готово и будет работать (ну судя по документации,которую я немного почитываю периодически)
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 18:05  [ТС]     Массив-ссылка на некоторые элементы другого массива #9
Цитата Сообщение от metaluga145 Посмотреть сообщение
Раз уж Вы пользуетесь boost, то используйте уже и их класс матриц, а еще лучше и их вектор. Думаю,если совместить это всем, то там уже все готово и будет работать (ну судя по документации,которую я немного почитываю периодически)
С удовольствием бы это сделал, если бы к моему приходу в проект, там уже не было бы нескольких тысяч строк, которые обращаются к этим матрицам. А переписывать весь проект ради матриц... и парой операций с перекидыванием между процессами не очень продуктивно.
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 18:09     Массив-ссылка на некоторые элементы другого массива #10
sl_k, тогда подождите еще. может кто что знает. Извините, помочь пока не могу.
буду следить за ответами Вам. самому стало интересно
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
06.05.2013, 19:19     Массив-ссылка на некоторые элементы другого массива #11
boost::reference_wrapper? http://www.boost.org/doc/libs/1_53_0/doc/html/ref.html
C++
1
std::vector<boost::reference_wrapper<Matrix>> matrixes;
Правда создавать так как вы хотите конечно не получится... Можно создать пустой и потом push_backать как надо, сделав предварительно reserve.

Добавлено через 6 минут
Но в теории можно развлечься помощнее и заюзать
C++
1
boost::optional<boost::reference_wrapper<T>>
Добавлено через 7 минут
Простенький пример идеи:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <vector>
#include <iostream>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
 
int main()
{
    int array[] = {1,2,3,4,5,6,7,8,9};
    int indices[] = {0, 5, 8};
    typedef boost::optional<boost::reference_wrapper<int>> value_t;
    std::vector<value_t> w_vector(10);
    for (int i = 0; i < sizeof(indices) / sizeof(*indices); ++i)
    {
        w_vector[indices[i]] = boost::ref(array[indices[i]]);
    }
    for (const auto& v : w_vector)
    {
        if (v.is_initialized())
        {
            std::cout << *v << std::endl;
        }
        else
        {
            std::cout << "uninit" << std::endl;
        }
    }
}
Добавлено через 15 минут
Вцелом reference_wrapper здесь и не нужен особо. Можно заюзать просто boost::optional<T&>.
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 20:12  [ТС]     Массив-ссылка на некоторые элементы другого массива #12
Цитата Сообщение от ForEveR Посмотреть сообщение
Добавлено через 15 минут
Вцелом reference_wrapper здесь и не нужен особо. Можно заюзать просто boost::optional<T&>.

то есть в моем случае
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef Matrix<int> MatrixInt;
std::vector<MatrixInt> mainVector(numMatrixes);
 
typedef optional<int&> intRef;
typedef Matrix<intRef> matrRef;
 
std::vector<matrRef> subVector(numMatrixes);
 
int indexArray[numIndexes];
 
for (int iMatrix = 0; iMatrix < numMatrixes; iMatrix++)
{  
    subVector[iMatrix].resize(numIndexes, numCols );
    for (int iIndex = 0; iIndex < numIndexes; iIndex ++)
        for (int iCol = 0; iCol < numCols; iCol++)
            // Описание трех скобок подряд:
            // доступ к нужной матрице: iMatrix
            // доступ к элементу матрицы: iIndex, iCol
            // и как аргумент для конструктора cоответствующий элемент из iMatrix: mainVector[iMatrix](indexArray[iIndex], iCol)
            subVector[iMatrix](iIndex, iCol)(mainVector[iMatrix](indexArray[iIndex], iCol));
}
И потом, чтобы получить значения из матрицы subVector'a нужно будет использовать оператор "*", но прямого доступа к объекту у нас не будет:
int x = 1 ;
int& rx = x ;
optional<int&> ora ;
optional<int&> orb(x) ;
ora = orb ; // now 'ora' is bound to 'x' through 'rx'
*ora = 2 ; // Changes value of 'x' through 'ora'
assert(x==2);

И для этого, кажется, надо будет переписывать save/load_construct_data для класса Matrix<T>, чего, собственно я и пытался избежать (если помните, у меня не совсем мир с этими функциями), думая, что можно как то сериализовать subVector как объект, а не как указатель (указатель ли это вообще?). Но это уже тема для boost serialization.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
07.05.2013, 08:18     Массив-ссылка на некоторые элементы другого массива #13
sl_k, Непонятно, как это задевает save/load... Это должно задевать только serialize по сути... Но как бы то ни было, можно ведь унаследоваться от optional-а (пока не особо представляю как это поможет, кроме переопределения оператора =) или реализовать нечто похожее под свои нужды...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <boost/optional.hpp>
 
template<typename T>
class optional_ref : public boost::optional<T&>
{
public:
   using boost::optional<T&>::optional;
   using boost::optional<T&>::operator =;
 
   optional_ref& operator = (const T& value)
   {
      this->operator *() = value;
   }
   operator T& ()
   {
      // assert is initialized
      return this->operator *();
   }
};
 
int main()
{
   int i = 0;
   int& ri = i;
   optional_ref<int> ref(ri);
   std::cout << ref << " " << i << std::endl;
   ref = 100;
   std::cout << ref << " " << i << std::endl;
}
Но это все адовый изврат и я абсолютно не понимаю как это должно работать... В любом случае придется делать копии при load-е так уж точно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.05.2013, 12:34     Массив-ссылка на некоторые элементы другого массива
Еще ссылки по теме:

C++ Получить третий массив C[15] по правилу: вначале элементы первого массива, затем элементы второго массива
C++ Записать в массив элементы другого массива
Возвести в квадрат некоторые элементы массива C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
07.05.2013, 12:34  [ТС]     Массив-ссылка на некоторые элементы другого массива #14
Цитата Сообщение от ForEveR Посмотреть сообщение
sl_k, Непонятно, как это задевает save/load... Это должно задевать только serialize по сути...
Не могу не согласиться.
Цитата Сообщение от ForEveR Посмотреть сообщение
Но это все адовый изврат и я абсолютно не понимаю как это должно работать... В любом случае придется делать копии при load-е так уж точно.
Вообще, думаю, что перепешу
save тоже, ведь загружать я хочу уже объекты в готовую матрицу, а не ссылки, поэтому буду делать это соответстующими методами serialize в соответствующих классах матрицы, а лишняя информация при сохранении ссылок нам не нужна.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace boost { 
namespace serialization {
 
template<class Archive, class T>
void save(
    Archive & ar, 
    const boost::optional< T > & t, 
    const unsigned int /*version*/
){
 
        ar << *t;
    }
}
вместо

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
namespace boost { 
namespace serialization {
 
template<class Archive, class T>
void save(
    Archive & ar, 
    const boost::optional< T > & t, 
    const unsigned int /*version*/
){
    const bool tflag = t.is_initialized();
    ar << boost::serialization::make_nvp("initialized", tflag);
    if (tflag){
        const boost::serialization::item_version_type item_version(version< T >::value);
        #if 0
        const boost::archive::library_version_type library_version(
            ar.get_library_version()
        };
        if(boost::archive::library_version_type(3) < library_version){
            ar << BOOST_SERIALIZATION_NVP(item_version);
        }
        #else
            ar << BOOST_SERIALIZATION_NVP(item_version);
        #endif
        ar << boost::serialization::make_nvp("value", *t);
    }
}
Yandex
Объявления
07.05.2013, 12:34     Массив-ссылка на некоторые элементы другого массива
Ответ Создать тему
Опции темы

Текущее время: 13:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru