Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Многомерный динамический массив

4.1K
13 ноября 2006 года
Zeran
80 / / 21.07.2006
Вобщем нужно создать динамический многомерный массив в Билдере 6м. Подскажите плиз как это правильно сделать?
Мне нуна сделать массив типа:
=
А[0][1][0] - имя1
A[0][1][1] - псевдоним1
=
А[1][1][0] - имя2
A[1][1][1] - псевдоним2
=
Вобщем в таком стиле...
3
13 ноября 2006 года
Green
4.8K / / 20.01.2000
 
Код:
vector< vector< vector<string> > >

а лучше
 
Код:
struct Tuple
{
   string[2];
};
vector< vector<Tuple> >

а ещё лучше давать полям имена, а не индексы
 
Код:
struct Tuple
{
   string name;
   string alias;
};
vector< vector<Tuple> >
4.1K
13 ноября 2006 года
Zeran
80 / / 21.07.2006
Кстате да, с именами мне будет поудобнее работать чем с индексами :)
Сенкс, дома проверю...если че - отпишусь :)
309
14 ноября 2006 года
el scorpio
1.1K / / 19.09.2006
Для Builder лучше использовать AnsiString, а также шаблон DynamicArray.
P.S. Это сугубо личное мнение, подкрепленное работой с Builder :D
3
14 ноября 2006 года
Green
4.8K / / 20.01.2000
Чем лучше? Обоснуй.
309
15 ноября 2006 года
el scorpio
1.1K / / 19.09.2006
Обосновываю:
1.1 AnsiString является стандартным строковым типом для всех компонентов VCL, посему переводить введённый AnsiString для обработки в string, чтобы потом перевести обратно в выводимый AnsiString - мысль на грани бреда.
1.2. AnsiString имеет множество методов для обработки самого себя, а также на него завязано ещё больше отдельных функций.
1.3. Конечно, использовать char[] всяко быстрее, но дело это сложное, как следствие, чревато множеством багов.

2.1. DynamicArray - стандартный класс Builder для работы с массивами изменяемого размера. Его методы позволяют не только изменять объём выделенной памяти, но и вызывать конструкторы/деструкторы для элементов.
2.2. Как я уже сказал, это сугубо личное мнение, по которому "Holy war" устраивать я не собираюсь ;)
3
15 ноября 2006 года
Green
4.8K / / 20.01.2000
Ок, воевать не будем, но я оглашу свой подход.

1. Лучше использовать стандартные типы данных языка там, где это возможно, если это не несет дополнительных рассходов.

2. Каждая отдельная библиотека должна выполнять свои отдельные функции. Универсализация библиотек приводит к большему уровню связанности и сложностям с оптимизицией и переносимостью.
VCL, MFC воспринимаются мной в первую очередь, как оконные библиотеки; во вторую - как врапперы над различными системными объектами. Контейнеры и пр. вещи, связанные с организацией данных в программе я бы использовал в последнюю очередь.

3. Надо по возможности обеспечивать как можно меньшее количество взаимосвязей между блоками программы.
2.9K
19 ноября 2006 года
Antisly
58 / / 22.04.2004
Кстати, раз уж речь зашла о многомерных массивах, то хотелось бы узнать, в курсе ли кто, как создать шаблон действительно многомерного массива, чтобы при объявлении можно было указать тип и размерность, и дальше работать как с массивом, созданным обычным образом? В свое время пытался на основе valarray и slice из STL написать подобный шаблон. Класс для 2-мерного массива сделал без проблем, но вот чтобы обобщить концепцию и зделать универсальный шаблон, ума не хватило. Запарился на operator [] и возвращаемых типах. Есть идеи?
309
20 ноября 2006 года
el scorpio
1.1K / / 19.09.2006
Antisly
Писали - в другой теме.
Но приемлемо (с точки зрения быстродействия и памяти) работающего способа реализации переопределиния оператора [] не нашли :(
4.1K
23 ноября 2006 года
Zeran
80 / / 21.07.2006
Цитата: Green
 
Код:
vector< vector< vector<string> > >

а лучше
 
Код:
struct Tuple
{
   string[2];
};
vector< vector<Tuple> >

а ещё лучше давать полям имена, а не индексы
 
Код:
struct Tuple
{
   string name;
   string alias;
};
vector< vector<Tuple> >



Прошу прощения за то что я такой ламер :) но у мну чето не получается...
Напиши плиз работающий пример с Билдера, как создать и записать чето в этот массив.
Сенкс...

3
23 ноября 2006 года
Green
4.8K / / 20.01.2000
Цитата: Zeran
Прошу прощения за то что я такой ламер :) но у мну чето не получается...
Напиши плиз работающий пример с Билдера, как создать и записать чето в этот массив.
Сенкс...


Код:
#include <string>
#include <vector>
using namespace std;


struct Tuple
{
    string name;
    string alias;
};

int main()
{
    vector< vector<Tuple> > arr(10, vector<Tuple>(10));
    arr[0][0].name = "name1";
    arr[0][0].alias = "alias1";

    return 0;
}
3
23 ноября 2006 года
Green
4.8K / / 20.01.2000
Цитата: Antisly
Кстати, раз уж речь зашла о многомерных массивах, то хотелось бы узнать, в курсе ли кто, как создать шаблон действительно многомерного массива, чтобы при объявлении можно было указать тип и размерность, и дальше работать как с массивом, созданным обычным образом? В свое время пытался на основе valarray и slice из STL написать подобный шаблон. Класс для 2-мерного массива сделал без проблем, но вот чтобы обобщить концепцию и зделать универсальный шаблон, ума не хватило. Запарился на operator [] и возвращаемых типах. Есть идеи?


А зачем?
Создать то можно, но это геморой будет ещё тот...
Ради аккадемического интереса набросал вот это:

Код:
#include <iostream>
#include <vector>
using namespace std;


template<typename T, int N>
class HyperCube
{
private:
    template<typename T, int N>
    struct _ContainerType
    {
        typedef typename _ContainerType<T,N-1>::Type ElemType;
        typedef vector<ElemType> Type;
        static Type init(const int* dims, const T& val) {
            return Type(dims[0], _ContainerType<T,N-1>::init(dims+1, val));
        }
    };

    template<typename T>
    struct _ContainerType<T,1>
    {
        typedef T ElemType;
        typedef vector<T> Type;
        static Type init(const int* dims, const T& val) {
            return Type(dims[0], val);
        }
    };

    typename _ContainerType<T,N>::Type data;

public:
    typedef typename _ContainerType<T,N>::ElemType ElemType;

    HyperCube(const int* dims, const T& val = T(0))
    :data( typename _ContainerType<T,N>::init(dims, val) )
    {}

    ElemType& operator[](int index) {
        return data[index];
    }
};


int main()
{
    const int dims[] = {2,2};
    HyperCube<int, 2> a(dims, 10);
    cout << a[1][1] << endl;

    return 0;
}

HyperCube<T, N>
T - это тип элемента (в примере int),
N - это количество пространств (в примере 2х мерный массив),

dims - это массив задающий размерность каждого пространства (в примере 2х2).
2.9K
23 ноября 2006 года
Antisly
58 / / 22.04.2004
Цитата: Green
А зачем?
Создать то можно, но это геморой будет ещё тот...
Ради аккадемического интереса набросал вот это...



Вот, вот. Примерно это я и хотел реализовать, только без вспомогательного массива dims (кстати, нафига он?). Постораюсь разобраться в написанном ;-)

Компилятор выдает ошибку на строке struct _ContainerType<T,1>: Invalid template declaration list. Разве так классы можно объявлять?

P.S. Кстати, почему до сих пор подобный класс не реализован в STL? Неоптимален с точки зрения времени исполнения?

3
23 ноября 2006 года
Green
4.8K / / 20.01.2000
Цитата: Antisly
Примерно это я и хотел реализовать, только без вспомогательного массива dims (кстати, нафига он?).


Ну а как задавать размерности?
Допустим есть трехмерный массив 5х3х8, так вот dims и будет задавать размеры каждого пространства, т.е. в данном случае:
const int dims[] = {5,3,8};

Цитата: Antisly

Компилятор выдает ошибку на строке struct _ContainerType<T,1>: Invalid template declaration list. Разве так классы можно объявлять?


Видимо, старенький компилятор.
struct _ContainerType<T,1> - это частичная специализация, вполне валидный в C++ прием, главное, чтоб компилятор поддерживал стандарт на таком уровне (я использовал MSVC 7.1).

Цитата: Antisly

P.S. Кстати, почему до сих пор подобный класс не реализован в STL? Неоптимален с точки зрения времени исполнения?


Да он в принципе не нужен...
Проще просо написать vector <vector> >, как показал в предыдущем примере.
Хотя, можно глянуть boost, там может и есть нечто подобное.

2.9K
30 ноября 2006 года
Antisly
58 / / 22.04.2004
Цитата: Green
Ну а как задавать размерности?


Мне кажется удобнее задавать размер многомерного массива через конструктор или специальные свойства/методы класса.


Цитата: Green
Видимо, старенький компилятор.


Эту ошибку выдавал C++ Builder 6. A Borland Developer Studio 2006 говорит: E2404 Dependent type qualifier 'HyperCube<T,2>::_ContainerType<int>' has no member type named 'Type'.
Так что может это сделано не по стандарту С++?


Цитата: Green
Да он в принципе не нужен...
Проще просо написать vector <vector> >, как показал в предыдущем примере.


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

3
01 декабря 2006 года
Green
4.8K / / 20.01.2000
Цитата: Antisly
Мне кажется удобнее задавать размер многомерного массива через конструктор или специальные свойства/методы класса.


Так он и задается в конструкторе:
HyperCube<int, 2> a(dims, 10); - это и есть вызов конструктора

Цитата: Antisly

Эту ошибку выдавал C++ Builder 6. A Borland Developer Studio 2006 говорит: E2404 Dependent type qualifier 'HyperCube<T,2>::_ContainerType<int>' has no member type named 'Type'.
Так что может это сделано не по стандарту С++?


Нет. Всё сделано по стандарту.
Это значит, что этот компилятор не поддерживает стандарт в той мере, в которой это надо для компиляции примера. Либо ты его неправильно скопировал.

Цитата: Antisly

Напсать-то проще, а вот пользоваться может быть нет.


И написать и использовать проще. В данном случае "написать" = "использовать".

Цитата: Antisly

Нет фунций удаления строк/столбцов, замены их местами, изменения их кол-ва с сохранением значений и т.д. и т.п.


почемуже нет? :)

arr[2].clear(); - удаление 2-го столбца,
arr[2] = arr[3]; - копирование
arr[2].resize() - изменение размера.

значительно проще обернуть конкретный набор векторов (т.е. например два вектора, один вложенный в другой, как в примере), чем делать всеразмерный контейнер. Универсальное - враг хорошего.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог