2013-04-29 5 views
1

Я относительный новичок в C++. Я работаю над моделью, связанной с прогнозированием финансовых свойств собственности, и у меня возникает несколько вопросов, связанных с настройкой структуры данных.Многомерные динамические массивы в классах в C++

Немного фона - конкретная задача, которую я пытаюсь сделать, это установить переменные класса для ключевых структур данных - одну такую ​​структуру, называемую PropFinance. Эта структура будет содержать всю мою ключевую информацию об определенном свойстве (с итерациями для каждого свойства в их коллекции), включая прогнозы будущей работы. Два основных аргумента, передаваемых программе, применимы ко всем свойствам, подлежащим оценке. (1) количество итераций (Итерации) - сколько раз мы собираемся генерировать прогноз (случайные итерации) (2) длина прогноза (NumofPeriods) - сколько периодов мы будем прогнозировать

Класс PropFinance содержит 79 переменных, содержащих сведения о свойствах. Простой пример - Расходы. Для расходов и многих моих переменных, подобных ему, мне нужно будет создать трехмерный массив двойников - по одному измерению для каждой итерации, по одному измерению для каждого прогнозируемого периода. Так что в идеале, я бы переменную Расходы:

class PropFinance { 
    double Expenses[Iterations][NumofPeriods]; 
} 

, но я не знаю, и Iterations NumofPeriods во время компиляции. Я знаю значение этих двух переменных в начале выполнения (и они будут постоянными для всех итераций/свойств текущего выполнения программы)

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

(1) Используйте (2) Используйте указатель в определении класса, а затем использовать новые и удалять управлять

Но даже с этими двумя вариантами я не уверен, что он будет работать с третьим измерением (все примеры, которые я видел, нуждались только в одном измерении, чтобы иметь динамический размер). Может ли кто-нибудь опубликовать либо устное объяснение, либо (лучше) простой пример кода, показывающий, как это будет работать в (1) или (2) выше? Любые рекомендации по выбору варианта будут оценены (но не хотят начинать «что лучше»). Кажется, что вектор более подходит, когда размер массива будет постоянно меняться, что здесь не так ...

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

Извините, что я не публиковал код - я могу попытаться что-то собрать, если люди не могут различить то, что я прошу сверху.

ответ

0

Идиоматическое решение состоит в том, чтобы избежать прямых распределений кучи массивов C и предпочесть контейнер STL, такой как std :: vector, который автоматически обрабатывает изменение размера, итерацию и доступ к элементу. Я очень рекомендую Эффективное STL Скотт Мейерс, что говорит о целесообразности каждого контейнера для различных приложений - вставка/удаление/сложность поиска gaurantees и т.д.

+0

Спасибо! Я хочу уточнить, что вектор является эффективным вариантом здесь - если бы я объявил эти массивы заранее (игнорируя проблему с информацией о времени компиляции), это было бы не намного быстрее, чем динамическое повторное измерение массива тысячи раз? Если я прогнозирую 180 периодов с 25 итерациями (прогон среднего размера), тогда я буду эффективно изменять размер массива 4500 раз. Разница между этими двумя альтернативами невелика? Извиняюсь за мой неосведомленный вопрос - я понимаю, что в случае с доразмерным я все равно должен будет выполнить 4500 заданий, так что, может быть, не намного медленнее? – brentf

+0

только вы знаете период и число итераций, которые вы можете предварительно выделить вектор с помощью std :: vector :: reserve (size_t). Эта функция помещает емкость контейнера в желаемое число, поэтому, когда вы можете избежать перераспределения, когда вы выполняете push_back. – ilmale

+0

Это имеет смысл - спасибо за разъяснение. – brentf

0

Если вам нужно более 2-х размеров (3, 4, 5 и т. д.). Самое легкое решение, которое я знаю, это использование multi_array, обеспечиваемого boost.

Если вам нужно только два размера массив, используйте вектор

std::vector<std::vector<double> > Expenses; 

Поскольку вы новичок, то лучше начать с более высокими компонентами уровня предоставляемых C++, даже вы знакомы с C++, вы должны остаться с эти компоненты высокого уровня тоже. Основные элементы C++ используются, когда вам нужно разработать некоторую инфраструктуру (вектор, список, интеллектуальные указатели, поток и т. д.).

#include <iostream> 
#include <vector> 

int main() 
{ 
    std::vector<std::vector<double> > expenses[10]; //contains 10 std::vector<double> 
    expenses[0].push_back(100); 

    std::cout<<expenses[0][0]<<std::endl; 

    expenses.push_back(std::vector<double>()); //now expenses has 11 std::vector<double> 

    return 0; 
} 

how to use vector

multi array

+0

Спасибо за быстрые ответы - это похоже на то, что вектор - это путь, на который можно пойти (если я не выйду за пределы двух измерений). Я буду работать над своим решением и позже разместить код. Просто уточнить - как только я объявил векторы, я просто использую push_back для их назначения? – brentf

0

Я думаю, что вы приближаетесь к объектно-ориентированному программированию неправильно.

Вместо того, чтобы иметь мастер-класс PropFinance со всем массивом размеров. Рассматривали ли вы, имеющие классы как Iteration, который имеет несколько Period, таких как

class Iteration 
{ 
    std::vector<Period­> _periods; 
} 

class Period 
{ 
public: 
    double Expense; 
} 

Тогда, как вы добавите больше размеров вы можете создать супер-классы PropFinance

class PropFinance 
{ 
    std::vector<Iteration> _iterations; 
} 

Это делает все более управляемым вместо того, чтобы глубоко вложенные массивы [] [] [] []. Как правило, всякий раз, когда у вас есть несколько массивов измерений, подумайте о создании подклассов, содержащих другое измерение.

Смежные вопросы