Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Многомерный вектор


Автор: Тигер 4.4.2010, 22:39
Как максимально быстро создать многомерные вектор.

скажем имеем массив, 

double a[4][4]={
    {1,3,6,1},
    {3,5,1,4},
    {5,2,4,5},
    {1,2,3,4}
    };

нужно получить 
vector < vector<double> >va;

кол-во элементов массива "a" неизвестно

Добавлено через 5 минут и 9 секунд
ес-но с циклами не лучший вариант.
тк. массив может иметь разный уровень вложенности, заранее неизвестный.

Автор: jonie 4.4.2010, 22:48
Цитата


кол-во элементов массива "a" неизвестно
в случае статического массива вполне известно.
в общем случае (надо проверить) можно сделать vector.resize(sizeof(a)/sizeof(a[0])) и сделать memcpy в &vector.front() .....
возможно элменты встанут "не туда"... в общем надо проверять....

Автор: Тигер 4.4.2010, 22:58
Код

            vector< vector<double> > va;
    int size=sizeof(a)/sizeof(a[0]); 
    va.resize(size);
    memcpy(&va.front(),a,size+1);

    for(int i=0;i<va.size();i++){
        for(int j=0;j<va[i].size();i++){
            cout <<va[i][j]<<" ";
        }
        cout <<endl;
    }


чёт не вышло.
вывело 0.0

Автор: GoldFinch 4.4.2010, 23:18
если нужна квадратная матрица, то проще сделать 1 вектор, и обращаться к элементам как
m[x+cx*y]

Автор: Тигер 5.4.2010, 07:37
не обязательно квадратная. уровень вложенности может быть разным.

может рекурсивный конструктор написать? я пробовал, у меня не получилось.

Добавлено @ 07:44
не знаю как узнать уровень вложенности

Код

template<typename _T,typename _T2>
void vConstruct(_T &res,_T2 arr){
    int size=sizeof(arr)/sizeof(arr[0]);
    for(int i=0;i<size;i++){
        if(!arr[i][0]){
           res.push_back(arr[i]);       
        }else{
           
           vConstruct(arr[i],sizeof(arr[i])/sizeof(_T2));
        }
    }
}


Автор: Тигер 5.4.2010, 14:06
Код

template<typename _T>
void* vConstruct(_T &arr){
     int size=sizeof(arr)/sizeof(arr[0]);
     vector<_T> *res=new vector<_T>; 
     for(int i=0;i<size;i++){
         if(sizeof(arr[i])/sizeof(_T)==0){
             cout <<"no no ";
         }else{
             cout <<"ee ee ";
         }
     }
     return &res;
}



как проверить переменную на массив. или получить уровень вложенности

Автор: Тигер 5.4.2010, 14:40
Код

template<typename _T>
void* vConstruct(_T &arr,unsigned int level){
     int size=sizeof(arr)/sizeof(arr[0]);
     vector<void *> *res=new vector<void *>; 
     for(int i=0;i<size;i++){
         if(level>1){
             level--;
             res->push_back(vConstruct(arr[i],level));
         }else{
             res->push_back(&arr[i]);
         }
     }
     return &res;
}


ругается не понятно поч.

Автор: Тигер 5.4.2010, 22:26
сделал через Ж.
оказалось что void* нельзя разименовывать. капец.

Автор: Ozerich 5.4.2010, 22:33
Цитата(Тигер @ 5.4.2010,  21:26)
сделал через Ж.
оказалось что void* нельзя разименовывать. капец.

Конечно нельзя. А откуда компилятор знает сколько место занимают данные которые там лежат?

Автор: Тигер 5.4.2010, 23:45
а как уже кроме void* можно получить произвольной вложенности vector<vector>

Автор: bsa 6.4.2010, 17:28
Тигер, через одномерный массив. Т.е. ты хранишь два одномерных массива: размерностей и данных. Доступ к каждому элементу через "вектор координат". Каждый элемент которого умножается на сумму размерностей ему предшествующих и суммируется с предыдущим умножением. В результате получаешь индекс в одномерном массиве.

Автор: Тигер 6.4.2010, 18:00
алгоритм представил, но реализация видится велосипедной и неудобной. хотелось бы на чистом stl
как быть с общим интерфейсом?

Автор: bsa 6.4.2010, 21:43
Тигер, не понял, а что в ней велосипедного?
Код
template<class T>
class Array
{
public:
   typedef std::vector<size_t> Vector;
   Array(const Vector &dims);
   T& operator[](const Vector &v);
   const T& operator[](const Vector &v) const;
private:
   const Vector dims_; ///< размерности
   std::vector<T> data_; ///< массив данных
};

Автор: Тигер 8.4.2010, 00:13
велосипедная наверное грубо. но это обёртка над stl, которая и так обёртка над стандартными возможностями.
хотя мб в СИ такая избыточность нормальна?

ну и не понятно как будет с остальным интерфейсом вектора. к примеру, надо будет мне это 
Код

double a[4][4][5]={...};
Array<double> ar(a);
a[0].size();

придётся значит переписывать метод size()

Автор: bsa 8.4.2010, 10:56
Тигер, начнем с того, что это не будет работать с приведенным мной примером, так как у меня оператора [] получающего на входе целое нет - его придется тебе самому писать. Не говоря уже о конструкторе.

Ты пытаешься создать свой собственный контейнер. Ты можешь использовать вектор, а можешь и не использовать. Это твое право. И никакой избыточности тут нет.

Автор: Тигер 8.4.2010, 17:18
мне интересно как делают это в крупных проектах.
есть же много вещей где может понадобится статичная инициализация многомерного массива. например массив конфигураций

Автор: mes 8.4.2010, 17:51
Цитата(Тигер @  5.4.2010,  13:06 Найти цитируемый пост)
как проверить переменную на массив. или получить уровень вложенности

не это ли Вы ищете :
http://codepad.org/Hk2dv5iu

Автор: Тигер 8.4.2010, 20:28
о нет =)
а если 10 урвней?

Добавлено через 57 секунд
лучше уж вручную уровень вложенности передвать. хотя я уверен есть способ его вычислить

Автор: mes 8.4.2010, 20:32
не могли бы еще раз сформулировать задачу, чтоб понятно было чего Вам надо.. 

Автор: bsa 9.4.2010, 10:56
Цитата(Тигер @  8.4.2010,  17:18 Найти цитируемый пост)
есть же много вещей где может понадобится статичная инициализация многомерного массива. например массив конфигураций 
массив конфигураций - это одномерный массив "сложных" структур данных. Лично я ума не приложу, зачем может понадобиться массив с неограниченным количеством измерений.

Автор: mes 9.4.2010, 11:41
Цитата(Тигер @  8.4.2010,  19:28 Найти цитируемый пост)
лучше уж вручную уровень вложенности передвать. хотя я уверен есть способ его вычислить 

если требуется вычислить уровень вложенности, чем прошлый пример не подошел ?
вот на его основе  : http://codepad.org/SSwAz5c9

Добавлено через 3 минуты и 9 секунд
Цитата(Тигер @  8.4.2010,  19:28 Найти цитируемый пост)
а если 10 урвней?

составляете общие функции переходники - типа библиотечки - а потом на их основе делаете что нужно.. 
пример показывал как узнать размерность, а уж к какому виду вы хотите привести полученную информацию, Вам решать ..
smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)