Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
13 / 13 / 4
Регистрация: 15.04.2010
Сообщений: 61
1

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

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

Author24 — интернет-сервис помощи студентам
У меня тут возникла идея. Есть большой двумерный массив, но не все строки этой матрицы нам нужны. Индексы нужных строк записаны в другой массив.
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, операция копирования создает лишний дискомфорт.

Собственно вопрос: как по хорошему реализовать такую матрицу?
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2013, 16:43
Ответы с готовыми решениями:

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

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

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

Как через массив ключей вывести нужные элементы другого массива
$array = array(1, 4); //это массив ключей $words = array(&quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;,...

13
244 / 245 / 38
Регистрация: 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];
как-то так. а потом на новый массив цеплять уже готовые строки, с помощью указателей
1
13 / 13 / 4
Регистрация: 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 надо стараться избегать работать с указателями и все-таки попробовать через ссылки.
0
244 / 245 / 38
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:14 4
Цитата Сообщение от sl_k Посмотреть сообщение
ввиду работы с boost serialization надо стараться избегать работать с указателями и все-таки попробовать через ссылки.
Почему?

Добавлено через 7 минут
пока не вижу никаких препятствий использовать указатели
1
13 / 13 / 4
Регистрация: 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 минут
Если, конечно, ничего не решится в ссылками, тогда придется раздувать классы и писать через указатели
0
244 / 245 / 38
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:39 6
Я не сильно с библиотеками boost знаком, но попробую разобраться.
Вы используете свой класс матриц?
мне кажется,что этот вопрос лучше перенести в раздел boost c++
1
13 / 13 / 4
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 17:54  [ТС] 7
Цитата Сообщение от metaluga145 Посмотреть сообщение
Вы используете свой класс матриц?
Да, класс матриц свой.

Цитата Сообщение от metaluga145 Посмотреть сообщение
мне кажется,что этот вопрос лучше перенести в раздел boost c++
Ну так как вопрос не совсем про сам буст и как его использовать, а скорее "можно ли сделать матрицу ссылок в с++?", то делать этому вопросу в boost c++ нечего, по-моему)
0
244 / 245 / 38
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 17:59 8
Цитата Сообщение от sl_k Посмотреть сообщение
Да, класс матриц свой.
Раз уж Вы пользуетесь boost, то используйте уже и их класс матриц, а еще лучше и их вектор. Думаю,если совместить это всем, то там уже все готово и будет работать (ну судя по документации,которую я немного почитываю периодически)
1
13 / 13 / 4
Регистрация: 15.04.2010
Сообщений: 61
06.05.2013, 18:05  [ТС] 9
Цитата Сообщение от metaluga145 Посмотреть сообщение
Раз уж Вы пользуетесь boost, то используйте уже и их класс матриц, а еще лучше и их вектор. Думаю,если совместить это всем, то там уже все готово и будет работать (ну судя по документации,которую я немного почитываю периодически)
С удовольствием бы это сделал, если бы к моему приходу в проект, там уже не было бы нескольких тысяч строк, которые обращаются к этим матрицам. А переписывать весь проект ради матриц... и парой операций с перекидыванием между процессами не очень продуктивно.
0
244 / 245 / 38
Регистрация: 08.04.2013
Сообщений: 927
06.05.2013, 18:09 10
sl_k, тогда подождите еще. может кто что знает. Извините, помочь пока не могу.
буду следить за ответами Вам. самому стало интересно
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.05.2013, 19:19 11
boost::reference_wrapper? http://www.boost.org/doc/libs/... l/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&>.
1
13 / 13 / 4
Регистрация: 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.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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-е так уж точно.
1
13 / 13 / 4
Регистрация: 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);
    }
}
0
07.05.2013, 12:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.05.2013, 12:34
Помогаю со студенческими работами здесь

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

Записать в массив такие элементы другого массива, что первая цифра четная, а вторая нечетная
Помогите, C# 3. Записать в массив С элементы массива М, заполненного двузначными числами, такие...

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

Дан двумерный массив,элементы массива умножить на число К.Вывести новый массив,проссумировать элементы массива по столбцам
Дан двумерный массив,элементы массива умножить на число К.Вывести новый массив,проссумировать...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru