Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> работа с трехмерными массивами 
:(
    Опции темы
ElKa
Дата 12.9.2010, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



подскажите пожалуйста как лучше организовать работу с трехмерными массивами
с С++ я только начала работать, еще многого не знаю

надо написать программу, обрабатывающую информацию о трехмерных объемах
т.е. надо будет в трехмерных, двумерных и одномерных массивах сохранять данные и постоянно с ними оперировать

вопросы такие
- стоит ли создавать классы для массивов и операторы в них для более удобной обработки, напр. оператор присваивания массива и т.д. и классы Array3, Array2, Array
- как декларировать указатель на трехмерный массив и инициализировать сам массив
- как удалять многомерные массивы? так же, как и одномерные? delete [] p..
- если трехмерные массивы могут иметь две размерности, а операции с ними одни и те же, как лучше с ними работать? 




Это сообщение отредактировал(а) ElKa - 12.9.2010, 18:26
PM   Вверх
vnf
Дата 12.9.2010, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: 1
Всего: 1



Цитата

- стоит ли создавать классы для массивов и операторы в них для более удобной обработки, напр. оператор присваивания массива и т.д. и классы Array3, Array2, Array

Стоит, очень стоит

Цитата

- как декларировать указатель на трехмерный массив и инициализировать сам массив

Как указатель на объект класса массива 
CMySuperArray * superarray = new CMySuperArray(5,5,8);
Цитата

- как удалять многомерные массивы? так же, как и одномерные? delete [] p..

delete superarray

Цитата

- если трехмерные массивы могут иметь две размерности, а операции с ними одни и те же, как лучше с ними работать? 


можно трактавать двухмерный массив как частный случай трёхмерного у которого одна из размерностей 1
можно трактавать одномерный массив как частный случай трёхмерного у которого две из размерностей 1
т.е. достаточного одного класса трехмерного массива

реализовать такой класс можно попробовать с помощью vector


PM MAIL   Вверх
ElKa
Дата 19.9.2010, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



vnf

спасибо! что-то я не разберусь с этими массивами

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

array.h
Код

#ifndef ARRAY_H_
#define ARRAY_H_
 
template <typename T, int s1, int s2, int s3>
class Array{

private:
    T *a_;
    int _size1;
    int _size2;
    int _size3;

public:
    Array();

    int getSize1();
    int getSize2();
    int getSize3();
    T &getValue(int i, int j, int k);
    void setValue(const T &value, int i, int j, int k);

    Array &operator=(Array &right);

    int &operator!=(Array &right);

    T &operator [](int i);

};


#endif /* ARRAY_H_ */

#include "array.cxx"



array.cxx
Код

#include <assert.h>

//!
/*!

  */
template <typename T, int s1, int s2, int s3>
Array<T,s1,s2,s3>::Array(): a_(new T[s1][s2][s3]), _size1(s1), _size2(s2), _size3(s3){}

template <typename T, int s1, int s2, int s3>
int Array<T,s1,s2,s3>::getSize1(){return _size1;}

template <typename T, int s1, int s2, int s3>
int Array<T,s1,s2,s3>::getSize2(){return _size2;}

template <typename T, int s1, int s2, int s3>
int Array<T,s1,s2,s3>::getSize3(){return _size3;}

template <typename T, int s1, int s2, int s3>
T &Array<T,s1,s2,s3>::getValue(int i, int j, int k){ return a_[i][j][k];}

template <typename T, int s1, int s2, int s3>
void Array<T,s1,s2,s3>::setValue(const T &value, int i, int j, int k){a_[i][j][k] = value;}

template <typename T, int s1, int s2, int s3>
Array &Array<T,s1,s2,s3>::operator=(Array &right){
        if(&right != this)
        {
            delete [] a_;
            _size1 = right.size1;
            _size2 = right.size2;
            _size3 = right.size3;
            a_ = new T[_size1][_size2][_size3];
            assert(a_ != 0);

            for(int i; i<_size1; ++i)
                for(int j; j<_size2; ++j)
                    for(int k; k<_size3; ++k)
                        a_[i][j][k] = right[i][j][k];
        }
        return *this;
    }

template <typename T, int s1, int s2, int s3>
int &Array<T,s1,s2,s3>::operator!=(Array &right)
    {
        if(_size1 != right.getSize1() || _size2 != right.getSize2() || _size3 != right.getSize3())
            return 1;

        for(int i; i<_size1; ++i)
            for(int j; j<_size2; ++j)
                for(int k; k<_size3; ++k)
                    if(a_[i][j][k] != right[i][j][k]) return 1;

        return 0;
    }

template <typename T, int s1, int s2, int s3>
T &Array<T,s1,s2,s3>::operator [](int i){return a_[i];}


вот здесь ошибка
Array &Array<T,s1,s2,s3>::operator=(Array &right)
говорит expected constructor, destructor, or type conversion before '&' token

и еще вопрос
как мне декларировать и создавать объекты этого класса в других классах?

Array [][][] arr;

int arr[2][3][5];

 
PM   Вверх
vnf
Дата 20.9.2010, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: 1
Всего: 1



Код

Array &Array<T,s1,s2,s3>::operator=(Array &right)


должно быть 

Код

Array<T,s1,s2,s3> &Array<T,s1,s2,s3>::operator=(Array<T,s1,s2,s3> &right)


то что в угловых скобках является неотемлимой часть имени класса

соответственно при использовании класса

Код

Array<int,7,8,10> arr


Вопрос: у вас везде будут испоьлзоваться массивы одинаковой размерности? Если нет, то размерности лs1 s2 s3 лучше не включать в праметры шаблона, а сделать аргументами конструктора

Код

template <typename T>
class Array{

private:
    T *a_;
    int _size1;
    int _size2;
    int _size3;

public:
    Array(int s1, int s2, int s3);

    int getSize1();
    int getSize2();
    int getSize3();
    T &getValue(int i, int j, int k);
    void setValue(const T &value, int i, int j, int k);

    Array &operator=(Array &right);

    int &operator!=(Array &right);

    T &operator [](int i);

};

template <typename T>
Array<T>::Array(int s1, int s2, int s3): a_(new T[s1][s2][s3]), _size1(s1), _size2(s2), _size3(s3){}


использование

Код

Array<int> arr(7,8,10);


ещё вашему классу нехватает деструктора, в котором нужно будет освобождать память delete [] a_


Это сообщение отредактировал(а) vnf - 20.9.2010, 07:29
PM MAIL   Вверх
ElKa
Дата 20.9.2010, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



vnf

спасибо, сейчас все внедрю и посмотрю, что будет  
PM   Вверх
Master01
Дата 20.9.2010, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 22.8.2007

Репутация: 2
Всего: 2



Если это не учебный проект, цель которого именно в том, чтобы "научится создавать собственные трёхмерные массивы", а вам просто нужен в вашей программе трёхмерный массив, то можете воспользоваться готовой реализацией - boost::multi_array

вот пример из хелпа

Код

typedef boost::multi_array<double, 3> array_type;
 array_type A(boost::extents[3][4][2]);
 A[0][0][0] = 3.14;
 assert(A[0][0][0] == 3.14);


Добавлено через 5 минут и 19 секунд
однако ничего так код для человека, который "с С++ я только начала работать, еще многого не знаю" smile
PM MAIL   Вверх
ElKa
Дата 21.9.2010, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



Master01

спасибо, этот вариант тоже попробую.. а проект не учебный, а очень сурьезный  

опять ошибка у меня.. посмотрите пожалуйста
пока код выглядит так

array.h
Код

#ifndef ARRAY_H_
#define ARRAY_H_
 
template <typename T>
class Array{

public:
    Array(int, int, int);
    ~Array();
    int getSize1();
    int getSize2();
    int getSize3();
    T &getValue(int i, int j, int k);
    void setValue(const T &value, int i, int j, int k);

    Array &operator=(Array &right);

    int &operator!=(Array &right);

    T &operator [](int i);
private:
    T *a_;
    int _size1;
    int _size2;
    int _size3;
};


#endif /* ARRAY_H_ */

#include "array.cxx"



array.cxx
Код

#include <assert.h>

template <typename T>
Array<T>::Array(int s1, int s2, int s3): a_(new T[s1][s2][s3]), _size1(s1), _size2(s2), _size3(s3){}

template <typename T>
Array<T>::~Array(){ delete [] a_;}

template <typename T>
int Array<T>::getSize1(){return _size1;}

template <typename T>
int Array<T>::getSize2(){return _size2;}

template <typename T>
int Array<T>::getSize3(){return _size3;}

template <typename T>
T &Array<T>::getValue(int i, int j, int k){ return a_[i][j][k];}

template <typename T>
void Array<T>::setValue(const T &value, int i, int j, int k){a_[i][j][k] = value;}

template <typename T>
Array<T> &Array<T>::operator=(Array<T> &right){
        if(&right != this)
        {
            delete [] a_;
            _size1 = right.size1;
            _size2 = right.size2;
            _size3 = right.size3;
            a_ = new T[_size1][_size2][_size3];
            assert(a_ != 0);

            for(int i; i<_size1; ++i)
                for(int j; j<_size2; ++j)
                    for(int k; k<_size3; ++k)
                        a_[i][j][k] = right[i][j][k];
        }
        return *this;
    }

template <typename T>
int &Array<T>::operator!=(Array &right)
    {
        if(_size1 != right.getSize1() || _size2 != right.getSize2() || _size3 != right.getSize3())
            return 1;

        for(int i; i<_size1; ++i)
            for(int j; j<_size2; ++j)
                for(int k; k<_size3; ++k)
                    if(a_[i][j][k] != right[i][j][k]) return 1;

        return 0;
    }

template <typename T>
T &Array<T>::operator [](int i){return a_[i];}



ошибка здесь
Array<T>::Array(int s1, int s2, int s3): a_(new T[s1][s2][s3]), _size1(s1), _size2(s2), _size3(s3){}

говорит  
    - `s2' cannot appear in a constant-
     expression
    - `s3' cannot appear in a constant-
     expression
PM   Вверх
vnf
Дата 21.9.2010, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: 1
Всего: 1



Код

new T[s1][s2][s3]


на 
Код

new T[s1*s2*s3]



здесь
Код

        for(int i; i<_size1; ++i)
            for(int j; j<_size2; ++j)
                for(int k; k<_size3; ++k)
                    if(a_[i][j][k] != right[i][j][k]) return 1;


нужно принициализировать i,j,k, иначе на дебажной будет работать а в релизе ошибки посыплются (int i = 0 и т.д.)

в setValue и getValue нужен контроль на выход за границы массива


Это сообщение отредактировал(а) vnf - 21.9.2010, 22:09
PM MAIL   Вверх
RedDigger
Дата 25.9.2010, 02:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Прошу прощения что влезаю в данный топик но не легче ли будет использовать обычные динамические массивы.. 
Создать класс для обработки 3х мерных массивов довольно просто. инициализировать подобные элементы также труда составить не должно.

Вот рабочая программка только что наваянная:
main.cpp
Код

#include "myarray.h"
#include <iostream>
using namespace std;

int main() {
        MyArray *array = new MyArray(3,3,3);
        bool ok;
        int result;
        // Writing test
        // Will be ok;
        if(array->setValue(2,2,1,225)) {
                cout << "Error." << endl;
        } else  cout << "Correct expected" << endl;

        // Will Fail
        if(array->setValue(2,6,1,225)) {
                cout << "Expected Error." << endl;
        } else  cout << "Correct" << endl;

        // Reading test
        // Will be ok
        result = array->getValue(2,2,1,ok);
        if(!ok) {
                cout << "Error" << endl;
        } else  cout << "Correct expected; Value: " << result << endl;
        // Will fail
        result = array->getValue(2,6,1,ok);
        if(!ok) {
                cout << "Error Expected" << endl;
        } else  cout << "Correct" << endl;


        delete array;
        return 0;
}

myarray.h
Код

#ifndef __MYARRAY_H
#define __MYARRAY_H

class MyArray {
public :
        // Constructor for array
        MyArray(int, int, int);
        ~MyArray();
        // accessors
        bool setValue(int, int, int, int);
        int getValue(int, int, int, bool&);
private:
        // Array pointer
        int *** m_array;
        // Maximums
        int m_xMax;
        int m_yMax;
        int m_zMax;
};

#endif


myarray.cpp 
Код

#include "myarray.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

MyArray::MyArray(int xMax, int yMax, int zMax) {
        int x,y,z;
        m_array = (int ***)malloc( xMax * sizeof(int));
        for(x = 0; x < xMax; x++) {
                m_array[x] = (int **) malloc( yMax * sizeof(int) );
                for(y = 0; y < yMax; y++) {
                        m_array[x][y] = (int *) malloc( zMax * sizeof(int) );
                        for(z = 0; z < zMax; z++) {
                                m_array[x][y][z] = 0;
                        }
                }
        }
        m_xMax = xMax;
        m_yMax = yMax;
        m_zMax = zMax;
        cout << "Object created" << endl;
}
MyArray::~MyArray() {
        int x,y;
        for(x = 0; x < m_xMax; x++) {
                for(y = 0; y < m_yMax; y++) {
                        delete m_array[x][y];
                }
                delete m_array[x];
        }
        cout << "Object deleted" << endl;

}
int MyArray::getValue(int x, int y, int z, bool &ok) {
        if(x >= m_xMax) {
                memset(&ok,0,1);
                return 0;
        }
        if(y >= m_yMax) {
                memset(&ok,0,1);
                return 0;
        }
        if(z >= m_zMax) {
                memset(&ok,0,1);
                return 0;
        }
        memset(&ok,1,1);
        return m_array[x][y][z];
}

bool MyArray::setValue(int x, int y, int z, int value) {
        if(x >= m_xMax) 
                return true;

        if(y >= m_yMax) 
                return true;

        if(z >= m_zMax) 
                return true;
        m_array[x][y][z] = value;
        return false;
}



Под линуксом работает нормально.. винды нет для проверки но теоретически работать должна и там.. Возможно изза разных компиляторов может чтото ругаться при сборке но все должно правиться без особого труда..

Надеюсь информация поможет.
PM MAIL Skype   Вверх
ValeryLaptev
Дата 25.9.2010, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Препод



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 19.8.2010
Где: Астрахань

Репутация: нет
Всего: 1



Если проект серьезный, как утверждает Elka, то лучше не писать велосипед, а использовать вектор векторов векторов. Из стандартной библиотеки.
 
PM MAIL   Вверх
RedDigger
Дата 25.9.2010, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Цитата(ValeryLaptev @ 25.9.2010,  07:41)
Если проект серьезный, как утверждает Elka, то лучше не писать велосипед, а использовать вектор векторов векторов. Из стандартной библиотеки.

Но при этом не учитывается что вектор занимает в памяти намного больше места нежели обычный массив. А если данных будет очень много??? результатом будет разница в скорости работы....

Холивар поднимать не хочу.. мое дело предложить.
PM MAIL Skype   Вверх
ElKa
Дата 25.9.2010, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



RedDigger

спасибо, попробую и так


ValeryLaptev

мне нужны именно массивы, потому что слишком много данных 
PM   Вверх
vnf
Дата 26.9.2010, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: 1
Всего: 1



ElKa

Вопрос: на сколько больше памяти занимает vector по сравнению с массивом?
PM MAIL   Вверх
RedDigger
Дата 26.9.2010, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Вектор - это структурный объект.. У него есть несколько больше возможностей и параметров которые возомжно не нужны в примере.. возможно следует только создать массив, удалить его при выходе и иметь возможность положить туда чтолибо или вытащить с него... 
Для огромного объема данных приходится иногда изобретать велосипед.. иногда и 28.4 колесный... лично мне не привыкать smile
PM MAIL Skype   Вверх
JackYF
Дата 29.9.2010, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(RedDigger @  25.9.2010,  12:03 Найти цитируемый пост)
Но при этом не учитывается что вектор занимает в памяти намного больше места нежели обычный массив.

Откуда информация?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
RedDigger
Дата 30.9.2010, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Цитата(JackYF @ 29.9.2010,  23:09)
Цитата(RedDigger @  25.9.2010,  12:03 Найти цитируемый пост)
Но при этом не учитывается что вектор занимает в памяти намного больше места нежели обычный массив.

Откуда информация?

Программа номер раз
Код

#include "boost/multi_array.hpp"
#include <iostream>

using namespace std;

int main(int argc, char ** argv) {
         typedef boost::multi_array<double, 3> array_type;
         array_type A(boost::extents[3][4][2]);
         printf("Sizeof boost::multi_array is %d\n", sizeof(A));
         return 0;
}



вывод - 
Код

Sizeof boost::multi_array is 80


программа номер два..
Код

#include "myarray.h"
#include <iostream>
using namespace std;

int main() {
        MyArray *array = new MyArray(3,3,3);
        cout << "Size of MyArray is " << sizeof(*array) << endl;
}


вывод - 
Код

Size of MyArray is 16



PM MAIL Skype   Вверх
Master01
Дата 30.9.2010, 13:33 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 22.8.2007

Репутация: 2
Всего: 2




Вы не совсем правильно понимаете эти результаты. Контейнер  будет занимать всегда на N  байт больше и это не зависит от количества элементов. Например, если память мне не изменяет, std::vector даже пустой (не содержащий полезных данных) занимает  где-то 20 байт.

т.о. если говорить, к примеру, о массиве int из 1024 элементов, требующих для хранения (предполагаем что int = 4 байта) 4 Кб, то эти 20 байт уже не кажутся таким кащунственным разбазареванием ресурсов.

А лепить что-то своё, ради выйгрыша в 20 байт весьма сомнительно ...

а вот политика выделения памяти, которой следует тот или иной контейнер - это действительно то, на что слежует обратить внимание, если нужно что-то оптимизировать.
PM MAIL   Вверх
RedDigger
Дата 30.9.2010, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Не учел... Спасибо за разъеснение.   
PM MAIL Skype   Вверх
Леопольд
Дата 30.9.2010, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(RedDigger @  25.9.2010,  13:03 Найти цитируемый пост)
Но при этом не учитывается что вектор занимает в памяти намного больше места нежели обычный массив.
Проблемма не в этом а в копировании векторов, которые являются элементами вектора. Делается глубокое копирование. Т.е. swap двух векторов один/два раза выделяется память под новый массив данных и трижды делается глубокая копия. IMHO это несколько расточительно.

Тут вроде-бы в помощь shared_ptr, но для того что-бы достучаться до элемента, придётся делать как-то так:
Код
typedef boost::shared_ptr<std::vector<int> > dim1_t;
typedef boost::shared_ptr<std::vector<dim1_t> > dim2_t;

std::vector<dim2_t> array;

array.push_back(dim2_t(new std::vector<dim1_t>));
array.back()->push_back(dim1_t(new std::vector<int>));
array.back()->back()->push_back(123);
std::cout<<(*(*array[0])[0])[0]<<std::endl;
// и т.д. и т.п.

Лично мне такой вариант не очень...

Это сообщение отредактировал(а) Леопольд - 30.9.2010, 16:43


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
JackYF
Дата 30.9.2010, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Леопольд @  30.9.2010,  15:29 Найти цитируемый пост)
трижды делается глубокая копия

Что-то я не понял, почему трижды. При глубоком копировании вектора векторов векторов векторов ... любой степени вложенности всё копируется единожды. По крайней мере, если вектор == std::vector. Но так должно быть и у любого другого вменяемого вектора.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Леопольд
Дата 2.10.2010, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(JackYF @  30.9.2010,  20:50 Найти цитируемый пост)
Что-то я не понял, почему трижды.
Я говорил про swap, который повсеместно используется в STL. Он создаёт временную копию.

Это сообщение отредактировал(а) Леопольд - 2.10.2010, 10:13


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 2.10.2010, 10:20 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Леопольд @  30.9.2010,  15:29 Найти цитируемый пост)
Т.е. swap двух векторов 


Цитата(Леопольд @  2.10.2010,  09:03 Найти цитируемый пост)
Я говорил про swap, который повсеместно используется в STL. Он создаёт временную копию.

я Вас правильно понял, что swap одного вектора в другой медленее чем просто копия ?





--------------------
PM MAIL WWW   Вверх
ElKa
Дата 2.10.2010, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



RedDigger

а как передавать такие массивы объектам других классов? 

мне нужно создавать объекты, которые содержат по два трехмерных массива 
в общем конструктор должен быть такой

Код

WCl::WCl(MyArray  p, MyArray n, int id)
{
    _p = p;
    _n = n;
    _id = id;
    }


и операторы наверное же тоже нужны

myarray.h
Код

        MyArray &operator=(MyArray &right);
        int &operator!=(MyArray &right);
        int &operator [](int i);

myarray.cxx
Код

MyArray &MyArray::operator=(MyArray &right){
        if(&right != this)
        {
            delete [] a_;
            _size1 = right.getSize1();
            _size2 = right.getSize2();
            _size3 = right.getSize3();
            a_ = new T[_size1*_size2*_size3];
            assert(a_ != 0);

            for(int i=0; i<_size1; ++i)
                for(int j=0; j<_size2; ++j)
                    for(int k=0; k<_size3; ++k)
                        a_[i*j*k] = &right[i*j*k];
        }
        return *this;
    }

int &MyArray::operator!=(MyArray &right)
    {
        if(_size1 != right.getSize1() || _size2 != right.getSize2() || _size3 != right.getSize3())
            return 1;

        for(int i=0; i<_size1; ++i)
            for(int j=0; j<_size2; ++j)
                for(int k=0; k<_size3; ++k)
                    if(a_[i][j][k] != right[i][j][k]) return 1;

        return 0;
    }

int &MyArray::operator [](int i)
    {
       return a_[i];
    }





Это сообщение отредактировал(а) ElKa - 2.10.2010, 17:58
PM   Вверх
JackYF
Дата 2.10.2010, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Леопольд @  2.10.2010,  09:03 Найти цитируемый пост)
Я говорил про swap, который повсеместно используется в STL. Он создаёт временную копию.

Я сомневаюсь, что swap двух векторов делает временную копию. Проверяли?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
RedDigger
Дата 2.10.2010, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 24.9.2010
Где: Москва

Репутация: 1
Всего: 1



Цитата(ElKa @ 2.10.2010,  17:25)
RedDigger

а как передавать такие массивы объектам других классов? 

мне нужно создавать объекты, которые содержат по два трехмерных массива 
в общем конструктор должен быть такой

Код

WCl::WCl(MyArray  p, MyArray n, int id)
{
    _p = p;
    _n = n;
    _id = id;
    }


и операторы наверное же тоже нужны

myarray.h
Код

        MyArray &operator=(MyArray &right);
        int &operator!=(MyArray &right);
        int &operator [](int i);

myarray.cxx
Код

MyArray &MyArray::operator=(MyArray &right){
        if(&right != this)
        {
            delete [] a_;
            _size1 = right.getSize1();
            _size2 = right.getSize2();
            _size3 = right.getSize3();
            a_ = new T[_size1*_size2*_size3];
            assert(a_ != 0);

            for(int i=0; i<_size1; ++i)
                for(int j=0; j<_size2; ++j)
                    for(int k=0; k<_size3; ++k)
                        a_[i*j*k] = &right[i*j*k];
        }
        return *this;
    }

int &MyArray::operator!=(MyArray &right)
    {
        if(_size1 != right.getSize1() || _size2 != right.getSize2() || _size3 != right.getSize3())
            return 1;

        for(int i=0; i<_size1; ++i)
            for(int j=0; j<_size2; ++j)
                for(int k=0; k<_size3; ++k)
                    if(a_[i][j][k] != right[i][j][k]) return 1;

        return 0;
    }

int &MyArray::operator [](int i)
    {
       return a_[i];
    }


Лучше всего передовать их по ссылке. В данном случае стек вызовов не переполняется лишними объектами. А внутри класса куда тебе надо завести данные создаешь член класса типа MyArray * (допустим)_b. 

Но с операторами ты немного намудрила. впринципе могу помочь.. 
Мои координаты - 
Skype: sl.spell
Mail: pn.spell{at}gmail.com
PM MAIL Skype   Вверх
Леопольд
Дата 3.10.2010, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(JackYF @  2.10.2010,  21:08 Найти цитируемый пост)
Я сомневаюсь, что swap двух векторов делает временную копию. Проверяли? 
Неа, не проверял, а зря. Вызывается векторный swap...


Это сообщение отредактировал(а) Леопольд - 3.10.2010, 17:01


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 3.10.2010, 17:33 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Леопольд @  3.10.2010,  16:01 Найти цитируемый пост)
 а зря

smile
Цитата

23.2.4.4 vector specialized algorithms
   template <class T, class Allocator>
   void swap(vector<T,Allocator>& x, vector<T,Allocator>& y);
 Effects:
   x.swap(y);


Это сообщение отредактировал(а) mes - 3.10.2010, 17:34


--------------------
PM MAIL WWW   Вверх
ElKa
Дата 5.10.2010, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



посмотрите пожалуйста код
почему то не те элементы вызываются и зависает ехе
массивы 3мерные и что-то я с этими указателями запуталась
и еще меня смущает operator [](int i), я его оставила таким же как для одномерных массивов, это правильно? 

array.h
Код

#ifndef ARRAY_H_
#define ARRAY_H_

class Array {
public:
    Array();
        Array(int, int, int);
        ~Array();
        int getSize1();
        int getSize2();
        int getSize3();
        bool setValue(int, int, int, float); 
        float getValue(int, int, int);
        Array &operator=(Array &right);
        int operator!=(Array &right);
        float** &operator[](int);

private:
        float *** a_;
        int _size1;
        int _size2;
        int _size3;
};

#endif


array.cxx
Код

#include "array.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

Array::Array(){}

Array::Array(int size1, int size2, int size3) {
       int i,j,k;
       a_ = (float ***)malloc( size1 * sizeof(int));
       // **a_ = new float[size1];
        for(i = 0; i < size1; i++) {
            a_[i] = (float **) malloc( size2 * sizeof(int) );
         //*a_[i] = new float[size2];
                for(j = 0; j < size2; j++) {
                    a_[i][j] = (float *) malloc( size3 * sizeof(int) );
             //    a_[i][j] = new float[size3];
                        for(k = 0; k < size3; k++) {
                                a_[i][j][k] = 0;
                        }
                }
        }
        _size1 = size1;
        _size2 = size2;
        _size3 = size3;
        cout << "array created" << endl;
}

Array::~Array() {
        int i,j;
        for(i = 0; i < _size1; i++) {
                for(j = 0; j < _size2; j++)
                        delete a_[i][j];
                delete a_[i];
        }
        cout << "array deleted" << endl;
}

int Array::getSize1(){
    return _size1;
}

 int Array::getSize2(){
     return _size2;
 }

 int Array::getSize3(){
     return _size3;
 }

bool Array::setValue(int x, int y, int z, float value) {
        if(x >= _size1)
                return true;
        if(y >= _size2)
                return true;
        if(z >= _size3)
                return true;
        a_[x][y][z] = value;
        return false;
}
   
float Array::getValue(int x, int y, int z) {
     if(x>=_size1 || y>=_size2 || z>=_size3){
         cout << "index out of range" << endl;
         return 0;
     }
     return a_[x][y][z];
}

Array &Array::operator=(Array &right){
       int i,j,k; 
       if(&right != this)
       {
           delete [] a_; 
           _size1 = right.getSize1(); 
           _size2 = right.getSize2(); 
           _size3 = right.getSize3(); 
           a_ = (float ***)malloc(_size1*_size2*_size3);
           assert(a_ != 0);

           for(i=0; i<_size1; i++){
              for(j=0; j<_size2; j++){
                 for(k=0; k<_size3; k++){
                  a_[i][j][k] = right[i][j][k]; //  вот здесь проблема!!!
                 }
              }
           }
                 }
        return *this;
}

int Array::operator!=(Array &right)
{
        if(_size1 != right.getSize1() || _size2 != right.getSize2() || _size3 != right.getSize3())
                return 1;

        int i,j,k;
        for(i=0; i<_size1; ++i)
                for(j=0; j<_size2; ++j)
                        for(k=0; k<_size3; ++k)
                                if(a_[i][j][k] != right[i][j][k]) return 1;

        return 0;
 }

float** &Array::operator [](int i)
    {
       return a_[i];
    }


 

PM   Вверх
Леопольд
Дата 6.10.2010, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



ElKa, c двумерными массивами код уже  сложно читать, а с тремя измерениями становится совсем тяжко, что чревато багами.

Индексы лучше переименовать в column, row, dept (или x, y ,z) во всём коде.

Если производительность не критична, то можно попробовать уйти от трехмерных массивов. Например, использовать что-то типа std::map<Point3d, float>.

IMHO логика в Array::setValue извращённая, если выход за границы, возвращает true, если всё ОК, возвращает false.

Макроса assert в релизе обычно нет (#define NDEBUG). Проверять им что недостаточно памяти не стоит.

Использовать malloc a потом delete[], это, по моему уже UB(undefined behaviour). Вместо malloc надо использовать new[]; Вызывает подозрение что на три выделения памяти делается два delete (а не три).

Если есть возможность то лучше использовать исключения (или assert, если позволяет специфика приложения) в Array::getValue и Array::setValue. Исключения более универсальны, assert не обработаешь, но зато нет накладных расходов.

В Array::operator= утечка памяти. Вместо трёх delete, всего один. И вообще, возникает ощущение что код писали как в мульте "Простоквашино" писали письмо. Строчку ты, строчку твой кот, а всё остальное Шарик... smile
Код
       a_ = (float ***)malloc( size1 * sizeof(int));
       // **a_ = new float[size1];
        for(i = 0; i < size1; i++) {
            a_[i] = (float **) malloc( size2 * sizeof(int) );
         //*a_[i] = new float[size2];
                for(j = 0; j < size2; j++) {
                    a_[i][j] = (float *) malloc( size3 * sizeof(int) );
             //    a_[i][j] = new float[size3];
                        for(k = 0; k < size3; k++) {
                                a_[i][j][k] = 0;
                        }
                }
        }
Код
a_ = (float ***)malloc(_size1*_size2*_size3);


Цитата(ElKa @  5.10.2010,  22:54 Найти цитируемый пост)
посмотрите пожалуйста код
Возникает ощущение что ты сама его не смотрела. Видимо практикуешь "слепой" десятипальцевый набор с завязанными глазами.. smile

P.S.
А может это просто стёб? Бывает и такое. Весьма похоже, надо сказать.

Это сообщение отредактировал(а) Леопольд - 6.10.2010, 10:25


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 6.10.2010, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Если оно надо, то можно допилить.

Код

#ifndef MULTI_ARRAY_HPP
#define MULTI_ARRAY_HPP

#include <cassert>
#include <cstdlib>
#include <cstring>

#include <stdexcept>
#include <algorithm>

template<typename T, std::size_t dimension>
class MultiArray
{
private:
    friend class MultiArray<T, dimension + 1>;

    T * m_data_;

    // lArg must not be zero
    static inline std::size_t multiply_(std::size_t lArg, std::size_t rArg)
    {
        std::size_t product = lArg * rArg;
        if(product / lArg != rArg)
        {
            throw std::overflow_error("MultiArray: std::size_t overflow");
        }
        return product;
    }

    static void calculateSizes_(std::size_t const (&init)[dimension], std::size_t (&sizes)[dimension])
    {
        sizes[dimension - 1] = init[dimension - 1];
        for(std::size_t i = 1; i < dimension; ++i)
        {
            std::size_t const next = dimension - i - 1;
            std::size_t const curr = dimension - i;

            sizes[next] = multiply_(sizes[curr], init[next]);
            if(sizes[next] == 0)
            {
                throw std::length_error("MultiArray: zero length");
            }
        }
    }

    static T * alloc_(std::size_t const (&init)[dimension])
    {
        std::size_t sizes_[dimension];
        calculateSizes_(init, sizes_);

        //sizes_[0] contains the array's total size
        std::size_t const sizeofPayload_ = multiply_(sizes_[0], sizeof(T));
        std::size_t const sizeofWithoutPayload_ = sizeof(std::size_t) * (dimension + 2);

        std::size_t * buffer_ = static_cast<std::size_t *>(::malloc(sizeofWithoutPayload_ + sizeofPayload_));
        if(buffer_ == NULL)
        {
            throw std::bad_alloc();
        }

        // init data buffer_
        buffer_[0] = dimension;
        std::copy(sizes_, sizes_ + dimension, buffer_ + 1);
        buffer_[dimension + 1] = 1;

        // construct data
        T * payload_ = reinterpret_cast<T *>(buffer_ + dimension + 2);
        for(std::size_t i = 0; i < sizes_[0]; ++i)
        {
            new(payload_ + i) T();
        }

        return payload_;
    }

    static T * alloc_(MultiArray const& copy)
    {
        std::size_t const sizeofWithoutPayload_ = sizeof(std::size_t) * (dimension + 2);
        std::size_t const sizeofPayload_ = copy.size() * sizeof(T);

        std::size_t * buffer_ = static_cast<std::size_t *>(::malloc(sizeofWithoutPayload_ + sizeofPayload_));
        if(buffer_ == NULL)
        {
            throw std::bad_alloc();
        }
        std::size_t * copyBuffer_ = reinterpret_cast<std::size_t *>(copy.m_data_) - dimension - 2;
        std::copy(copyBuffer_, copyBuffer_ + dimension + 2, buffer_);

        // construct data
        T * payload_ = reinterpret_cast<T *>(buffer_ + dimension + 2);
        std::copy(copy.m_data_, copy.m_data_ + copy.size(), payload_);

        return payload_;
    }

    void destroy_() throw()
    {
        std::size_t const size_ = this->size();
        for(std::size_t i = 0; i < size_; ++i)
        {
            this->m_data_[i].~T();
        }
        std::size_t * rawMemory_ = reinterpret_cast<std::size_t *>(this->m_data_) - dimension - 2;
        ::free(rawMemory_);
    }

    struct Proxy_
    {
        std::size_t * m_sizes;
        T * m_data;

        Proxy_(std::size_t * sizes, T * data) :
            m_sizes(sizes), m_data(data)
        {}

        typename MultiArray<T, dimension - 1>::Proxy_ operator[] (std::size_t i)
        {
            T * leftBound = this->m_data;
            T * rightBound = this->m_data + this->m_sizes[0] - 1;

            std::size_t * sizes_ = this->m_sizes + 1;
            T * data_ = leftBound + multiply_(sizes_[0], i);
            if(data_ < leftBound || rightBound < data_)
            {
                throw std::range_error("MultiArray: out of bounds");
            }
            return MultiArray<T, dimension - 1>::getProxy_(sizes_, data_);
        }

        std::size_t size() const
        {
            return *this->m_sizes[0];
        }

        Proxy_ & operator=(Proxy_ const& rArg)
        {
            std::size_t const sizeofThis = this->m_sizes[0];
            std::size_t const sizeofThat = rArg.m_sizes[0];
            if(sizeofThis != sizeofThat)
            {
                throw std::length_error("MultiArray: unequal lenght");
            }
            std::copy(rArg.m_data, rArg.m_data + sizeofThat, this->m_data);

            return *this;
        }
    };

    struct NothrowProxy_
    {
        std::size_t * m_sizes;
        T * m_data;

        MultiArray *const m_parent;

        NothrowProxy_(std::size_t * sizes, T * data, MultiArray *const parent = NULL) :
            m_sizes(sizes), m_data(data), m_parent(parent)
        {}

        typename MultiArray<T, dimension - 1>::NothrowProxy_ operator[] (std::size_t i)
        {
            std::size_t * sizes_ = this->m_sizes + 1;
            T * data_ = this->m_data + sizes_[0] * i;
            return MultiArray<T, dimension - 1>::getNothrowProxy_(sizes_, data_);
        }

        std::size_t size() const
        {
            return this->m_sizes[0];
        }

        NothrowProxy_ & operator=(NothrowProxy_ const& rArg)
        {
            std::size_t const sizeofThat = rArg.m_sizes[0];
            std::copy(rArg.m_data, rArg.m_data + sizeofThat, this->m_data);

            return *this;
        }

//        TODO: array copy
        NothrowProxy_ & operator=(MultiArray const& copy)
        {
            if(this->m_parent != NULL)
            {
                T * buffer_ = alloc_(copy);
                this->m_parent->destroy_();
                this->m_parent->m_data_ = buffer_;
            }

            return *this;
        }

        void reshape(std::size_t const (&init)[dimension])
        {
            std::size_t sizes_[dimension];
            calculateSizes_(init, sizes_);

            //sizes_[0] contains the array's total size
            std::size_t * buffer_ = reinterpret_cast<std::size_t *>(this->m_data) - 1 - dimension;
            std::copy(sizes_ + 1, sizes_ + dimension, buffer_ + 1);
        }
    };

    static Proxy_ getProxy_(std::size_t * sizes, T * data)
    {
        return Proxy_(sizes, data);
    }

    static NothrowProxy_ getNothrowProxy_(std::size_t * sizes, T * data)
    {
        return NothrowProxy_(sizes, data);
    }

public:

    MultiArray(std::size_t const (&init)[dimension]) :
        m_data_(alloc_(init))
    {}

    MultiArray(MultiArray const& copy) :
        m_data_(alloc_(copy))
    {}

    typename MultiArray<T, dimension - 1>::Proxy_ operator[] (std::size_t i)
    {
        std::size_t * sizes_ = reinterpret_cast<std::size_t *>(this->m_data_) - dimension - 1;
        T * leftBound = this->m_data_;
        T * rightBound = this->m_data_ + sizes_[0] - 1;

        ++sizes_;
        T * data_ = leftBound + multiply_(sizes_[0], i);
        if(data_ < leftBound || rightBound < data_)
        {
            throw std::range_error("MultiArray: out of bounds");
        }
        return MultiArray<T, dimension - 1>::getProxy_(sizes_, data_);
    }

    NothrowProxy_ operator() (std::nothrow_t const&)
    {
        std::size_t * sizes_ = reinterpret_cast<std::size_t *>(this->m_data_) - dimension - 1;
        return NothrowProxy_(sizes_, this->m_data_, this);
    }

    MultiArray & operator= (MultiArray const& copy)
    {
        T * buffer_ = alloc_(copy);
        this->destroy_();
        this->m_data_ = buffer_;

        return *this;
    }

    void reshape(std::size_t const (&init)[dimension])
    {
        std::size_t sizes_[dimension];
        calculateSizes_(init, sizes_);

        //sizes_[0] contains the array's total size
        std::size_t * buffer_ = reinterpret_cast<std::size_t *>(this->m_data_) - 1 - dimension;
        if(sizes_[0] != buffer_[0])
        {
            throw std::invalid_argument("MultiArray: reshape unequal length");
        }

        std::copy(sizes_ + 1, sizes_ + dimension, buffer_ + 1);
    }

    ~MultiArray()
    {
        this->destroy_();
    }

    std::size_t size() const
    {
        return *(reinterpret_cast<std::size_t *>(this->m_data_) - dimension - 1);
    }
};

template<typename T>
class MultiArray<T, 0>
{
private:
    MultiArray(MultiArray const&);
    MultiArray & operator=(MultiArray const&);

    friend class MultiArray<T, 1>;

    typedef T & Proxy_;
    typedef T & NothrowProxy_;

    static Proxy_ getProxy_(std::size_t *, T * data)
    {
        return *data;
    }

    static NothrowProxy_ getNothrowProxy_(std::size_t *, T * data)
    {
        return *data;
    }

};

#endif
Код
#include <iostream>
#include <string>

#include <boost/multi_array.hpp>
#include <boost/lexical_cast.hpp>

#include "multi_array.hpp"

inline void testSpeed ()
{
    static std::size_t nativeArray[100][100][100];
    clock_t start = clock();
    for(std::size_t ni = 0; ni < 100; ++ni )
        for(std::size_t i = 0; i < 100; ++i)
            for(std::size_t j = 0; j < 100; ++j)
                for(std::size_t k = 0; k <100; ++k)
                    nativeArray[i][j][k] = 0;
    clock_t stop = clock();
    std::cout << "nativeArray: " << double((stop - start)) / CLOCKS_PER_SEC << " seconds" << std::endl;

    start = clock();
    typedef boost::multi_array<std::size_t, 3> array_type;
    typedef array_type::index index;
    array_type boostArray(boost::extents[100][100][100]);

    for(std::size_t ni = 0; ni < 100; ++ni )
        for(std::size_t i = 0; i < 100; ++i)
            for(std::size_t j = 0; j < 100; ++j)
                for(std::size_t k = 0; k <100; ++k)
                    boostArray[i][j][k] = 0;
    stop = clock();
    std::cout << "boostArray: " << double((stop - start)) / CLOCKS_PER_SEC << " seconds" << std::endl;

    start = clock();
    std::size_t init[] = {100, 100, 100};
    MultiArray<std::size_t, 3> myArray(init);

    for(std::size_t ni = 0; ni < 100; ++ni )
        for(std::size_t i = 0; i < 100; ++i)
            for(std::size_t j = 0; j < 100; ++j)
                for(std::size_t k = 0; k <100; ++k)
                    myArray(std::nothrow)[i][j][k] = 0;
    stop = clock();
    std::cout << "myArray(std::nothrow): " << double((stop - start)) / CLOCKS_PER_SEC << " seconds" << std::endl;

    start = clock();
    for(std::size_t ni = 0; ni < 100; ++ni )
        for(std::size_t i = 0; i < 100; ++i)
            for(std::size_t j = 0; j < 100; ++j)
                for(std::size_t k = 0; k <100; ++k)
                    myArray[i][j][k] = 0;
    stop = clock();
    std::cout << "myArray: " << double((stop - start)) / CLOCKS_PER_SEC << " seconds" << std::endl;
}

std::size_t testNo = 0;
bool printPassed = true;
#define BOOL_TEST(EXPR) \
++testNo;\
if(EXPR)\
{\
    if(printPassed)\
    {\
        std::cerr << "test " << testNo << ": PASSED (" #EXPR ")\n" << std::flush;  \
    }\
}\
else\
{\
    std::cerr << "test " << testNo << ": FAILED (" #EXPR ")\n" << std::flush;  \
}

inline void testSuite()
{
    {
        std::size_t init[] = {2, 5, 3};
        MultiArray<std::size_t, 3> array(init);

        std::size_t d0 = 0;
        std::size_t d1 = 0;
        std::size_t d2 = 0;

        BOOL_TEST(array.size() == 30)

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
                for(d2 = 0; d2 < init[2]; ++d2)
                {
                    array[d0][d1][d2] = d0 * 100 + d1 * 10 + d2;
                }

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
                for(d2 = 0; d2 < init[2]; ++d2)
                {
                    BOOL_TEST(array[d0][d1][d2] == d0 * 100 + d1 * 10 + d2);
                }

        array[0] = array[1];
        for(d1 = 0; d1 < init[1]; ++d1)
            for(d2 = 0; d2 < init[2]; ++d2)
            {
                BOOL_TEST(array[0][d1][d2] == array[1][d1][d2]);
            }

        array[0][0] = array[0][1];
        for(d2 = 0; d2 < init[2]; ++d2)
        {
            BOOL_TEST(array[0][0][d2] == array[0][1][d2]);
        }

        array[0][0][0] = array[0][0][1];
        BOOL_TEST(array[0][0][0] == array[0][0][1]);
    }

    {
        std::size_t init[] = {2, 3};
        MultiArray<std::size_t, 2> array(init);

        std::size_t d0 = 0;
        std::size_t d1 = 0;

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
            {
                array[d0][d1] = d0 * 10 + d1;
            }

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
            {
                BOOL_TEST(array[d0][d1] == d0 * 10 + d1);
            }

        std::size_t newShape1[] = {3, 2};
        array.reshape(newShape1);
        BOOL_TEST(array[0][0] == 00);
        BOOL_TEST(array[0][1] == 01);
        BOOL_TEST(array[1][0] == 02);
        BOOL_TEST(array[1][1] == 10);
        BOOL_TEST(array[2][0] == 11);
        BOOL_TEST(array[2][1] == 12);

        std::size_t newShape2[] = {1, 6};
        array.reshape(newShape2);
        BOOL_TEST(array[0][0] == 00);
        BOOL_TEST(array[0][1] == 01);
        BOOL_TEST(array[0][2] == 02);
        BOOL_TEST(array[0][3] == 10);
        BOOL_TEST(array[0][4] == 11);
        BOOL_TEST(array[0][5] == 12);

        std::size_t newShape3[] = {6, 1};
        array.reshape(newShape3);
        BOOL_TEST(array[0][0] == 00);
        BOOL_TEST(array[1][0] == 01);
        BOOL_TEST(array[2][0] == 02);
        BOOL_TEST(array[3][0] == 10);
        BOOL_TEST(array[4][0] == 11);
        BOOL_TEST(array[5][0] == 12);
    }

    {
        std::size_t init[] = {2, 5, 3};
        MultiArray<std::size_t, 3> array(init);

        std::size_t d0 = 0;
        std::size_t d1 = 0;
        std::size_t d2 = 0;

        BOOL_TEST(array(std::nothrow).size() == 30)

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
                for(d2 = 0; d2 < init[2]; ++d2)
                {
                    array(std::nothrow)[d0][d1][d2] = d0 * 100 + d1 * 10 + d2;
                }

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
                for(d2 = 0; d2 < init[2]; ++d2)
                {
                    BOOL_TEST(array(std::nothrow)[d0][d1][d2] == d0 * 100 + d1 * 10 + d2);
                }

        array(std::nothrow)[0] = array(std::nothrow)[1];
        for(d1 = 0; d1 < init[1]; ++d1)
            for(d2 = 0; d2 < init[2]; ++d2)
            {
                BOOL_TEST(array(std::nothrow)[0][d1][d2] == array(std::nothrow)[1][d1][d2]);
            }

        array(std::nothrow)[0][0] = array(std::nothrow)[0][1];
        for(d2 = 0; d2 < init[2]; ++d2)
        {
            BOOL_TEST(array(std::nothrow)[0][0][d2] == array(std::nothrow)[0][1][d2]);
        }

        array(std::nothrow)[0][0][0] = array(std::nothrow)[0][0][1];
        BOOL_TEST(array(std::nothrow)[0][0][0] == array(std::nothrow)[0][0][1]);
    }

    {
        std::size_t init[] = {2, 3};
        MultiArray<std::size_t, 2> array(init);

        std::size_t d0 = 0;
        std::size_t d1 = 0;

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
            {
                array(std::nothrow)[d0][d1] = d0 * 10 + d1;
            }

        for(d0 = 0; d0 < init[0]; ++d0)
            for(d1 = 0; d1 < init[1]; ++d1)
            {
                BOOL_TEST(array(std::nothrow)[d0][d1] == d0 * 10 + d1);
            }

        std::size_t newShape1[] = {3, 2};
        array(std::nothrow).reshape(newShape1);
        BOOL_TEST(array(std::nothrow)[0][0] == 00);
        BOOL_TEST(array(std::nothrow)[0][1] == 01);
        BOOL_TEST(array(std::nothrow)[1][0] == 02);
        BOOL_TEST(array(std::nothrow)[1][1] == 10);
        BOOL_TEST(array(std::nothrow)[2][0] == 11);
        BOOL_TEST(array(std::nothrow)[2][1] == 12);

        std::size_t newShape2[] = {1, 6};
        array(std::nothrow).reshape(newShape2);
        BOOL_TEST(array(std::nothrow)[0][0] == 00);
        BOOL_TEST(array(std::nothrow)[0][1] == 01);
        BOOL_TEST(array(std::nothrow)[0][2] == 02);
        BOOL_TEST(array(std::nothrow)[0][3] == 10);
        BOOL_TEST(array(std::nothrow)[0][4] == 11);
        BOOL_TEST(array(std::nothrow)[0][5] == 12);

        std::size_t newShape3[] = {6, 1};
        array(std::nothrow).reshape(newShape3);
        BOOL_TEST(array(std::nothrow)[0][0] == 00);
        BOOL_TEST(array(std::nothrow)[1][0] == 01);
        BOOL_TEST(array(std::nothrow)[2][0] == 02);
        BOOL_TEST(array(std::nothrow)[3][0] == 10);
        BOOL_TEST(array(std::nothrow)[4][0] == 11);
        BOOL_TEST(array(std::nothrow)[5][0] == 12);

        MultiArray<std::size_t, 2> array1(init);
        array1(std::nothrow) = array;
        BOOL_TEST(array1[0][0] == array(std::nothrow)[0][0]);
        BOOL_TEST(array1[1][0] == array(std::nothrow)[1][0]);
        BOOL_TEST(array1[2][0] == array(std::nothrow)[2][0]);
        BOOL_TEST(array1[3][0] == array(std::nothrow)[3][0]);
        BOOL_TEST(array1[4][0] == array(std::nothrow)[4][0]);
        BOOL_TEST(array1[5][0] == array(std::nothrow)[5][0]);

        array(std::nothrow).reshape(newShape2);
        array1 = array;
        BOOL_TEST(array(std::nothrow)[0][0] == array1[0][0]);
        BOOL_TEST(array(std::nothrow)[0][1] == array1[0][1]);
        BOOL_TEST(array(std::nothrow)[0][2] == array1[0][2]);
        BOOL_TEST(array(std::nothrow)[0][3] == array1[0][3]);
        BOOL_TEST(array(std::nothrow)[0][4] == array1[0][4]);
        BOOL_TEST(array(std::nothrow)[0][5] == array1[0][5]);
    }
}

int main()
{
    testSuite();

    testSpeed();

    return 0;
}

LWS

Это сообщение отредактировал(а) Леопольд - 31.10.2010, 13:30


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 7.10.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Леопольд @  6.10.2010,  12:05 Найти цитируемый пост)
Если оно надо, то можно допилить.
"допилил"...


Это сообщение отредактировал(а) Леопольд - 8.10.2010, 00:00


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
ElKa
Дата 10.10.2010, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: нет
Всего: 4



Цитата(Леопольд @ 6.10.2010,  09:59)
И вообще, возникает ощущение что код писали как в мульте "Простоквашино" писали письмо. Строчку ты, строчку твой кот, а всё остальное Шарик...  

ну в общем так и есть, если просмотреть комменты выше, то это должно быть понятно  smile 

за помощь спасибо, сейчас все внедрю и посмотрю, что будет 
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1614 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.