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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
#1

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

06.05.2013, 16:43. Просмотров 779. Ответов 13
Метки нет (Все метки)

У меня тут возникла идея. Есть большой двумерный массив, но не все строки этой матрицы нам нужны. Индексы нужных строк записаны в другой массив.
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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Массив-ссылка на некоторые элементы другого массива (C++):

Разделить элементы одного массива на элементы другого массива, записать результат в третий массив - C++
Как разделить элементы одного массива на элементы другого массива? есть массив a и есть массив b. размеры a=b. ввожу новый массив,...

Записать в массив элементы другого массива - C++
Дан массив B(15). Записать в массив элементы массива B&gt;5. Помогите, пожалуйста, составить программу, до завтра нужно для зачёта.

Ввод в массив элементы другого массива. - C++
Здравствуйте, в задаче нужно из текстовой строки удалить пробелы и переписать символы в другой массив vector. Пробелы я нашёл как убрать, а...

Сформировать массив записав элементы одного массива на четные места, а другого на нечетные - C++
Привет друзья! Понимаю логику данной программы, но плохо знаю язык c++, прошу дать код хотя бы основы программы. Даны 2 массива...

Есть два потока и глобальный массив, могут ли потоки перепутать элементы глобального массива или другого контейнера? - C++
Начать с массивов, допустим То есть ситуация такая: пусть имеется два потока и глобальный массив элементов int из двух элементов, один...

Возвести в квадрат некоторые элементы массива - C++
Если у массива А(20) есть элемент, равный квадрату последнего элемента,то все элементы, следующие за ним, возвести в квадрат, иначе вывести...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 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
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 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-е так уж точно.
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);
    }
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.05.2013, 12:34
Привет! Вот еще темы с ответами:

Перед указанным элементом массива вставить все элементы другого массива - C++
Даны одномерные массивы a и b, и число р. Вставить в массив a перед элементом с индексом р все элементы массива b. Добавлено через...

Вывести некоторые элементы массива в двоичный файл - C++
исправьте пожалуйста #include &lt;cstdio&gt; #include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; ...

Массив: Сформировать третий массив, в который включить все отрицательные элементы массива А и все максимальные элементы массива В. - C++
Даны массивы целых чисел A и B. Сформировать третий массив, в который включить все отрицательные элементы массива А и все максимальные...

Удалить из двумерного массива элементы другого массива - C++
Всем доброе время суток) Сегодня столкнулся с таким заданием: нужно Ввести с клавиатуры прямоугольную матрицу и вектор целых чисел. Найти...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
07.05.2013, 12:34
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru