Модераторы: 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   Вверх
Страницы: (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.1338 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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