Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Помогите выбрать структуру данных


Автор: Retamon 24.9.2013, 15:42
Нужно написать программу, помогите выбрать для нее структуру данных.
Даны материалы, зависящие от других. Например Комп - это Системник + Монитор, а например Системник в свою очередь - Мать + Память и т.д....
В каком формате хранить, и как обрабатывать?
Чтобы например выбрать в списке комп, и оно выдало весь список составляющих, все глубже и глубже по уровням?
Я начинающий программист, но не тупой вроде smile
Поэтому, если знаете какой точно здесь нужен формат данных, просто тыкните его, и книжку или ссылку, куда что читать. Разжевывать не надо, сразу посылать РТФМ - тоже.

Автор: jonie 24.9.2013, 19:10
может вы все же имеете в виду декомпозицию системы? Тогда это лаба в чистом виде же, а для лаб у нас целый раздел имеется...

Автор: jsharp36 24.9.2013, 22:24
Цитата

   Я начинающий программист, но не тупой вроде smile
   

Совсем начинающий, судя с вопроса )
C# - объектно-ориентированный язык, поэтому классы - родной формат. Там есть типы, вроде Tuple<>, но это уже не совсем хорошие типы, а удобные только для использования "на коротких дистанциях", чтобы не писать класс. К свойствам Tuple обращаться неудобно, т.к. нет читаемости, не ясно, что такое Item1, Item2 и т.д.
Класс SystemBlock содержит два свойства MotherBoard и Memory. Тип их определяет то, что имелось ввиду под "и т.д.". Если дальше ничего, то возможно, достаточно string. Далее, класс Computer содержит два свойства: SystemBlock (типа SystemBlock, можете назвать как-то разными синонимами, чтобы отличать класс и свойство. Это ссылка на объект класса "Системник") и свойство Monitor, тоже если дальше глубины нет, то string.

Цитата

   Чтобы например выбрать в списке комп, и оно выдало весь список составляющих...
   

Сами ответили, что это список, т.е. скорее List<> или какой-то наследник листа.

Выбирать что угодно, например, количество компьютеров с мониторами Sumsung - Linq. Для разворачивания не требуется.
Такое моделирование с помощью классов - самое верное и правильное с т.з. моделирования предметной области и статической типизации.
Но может быть неудобным с т.з. именно этой задачи. На каждом уровне, например, нужен свой код, чтобы двигаться вглубь и количество уровней строго задано в коде.
Тогда просто посмотрите, как создаются структуры "дерево". В общем, надо класс Node (узел), и чтобы он мог содержать другие узлы.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Помогите-выбрать-структуру-данных-id5241894eae2015f106000003#findElement_E7045_5241e6f8ae2015d428001c71_0

Автор: dzaraev 25.9.2013, 07:38
Если "ткнуть книжкуссылку", то вот довольно известный труд Буча: http://rutracker.org/forum/viewtopic.php?t=3343958 Также вам поможет гугель по запросу "объектно-ориентированный анализ". В общем вы затронули истинно-инженерскую тему - создание модели окружающего мира  smile.
Ну и конечно же изучайте паттерны проектирования, начать можно с тех же GoF - http://ru.wikipedia.org/wiki/Design_Patterns .

Про мониторы - накидал небольшой пример: есть общая абстракция над компонентами и есть конкретные компоненты. Можно выполнять обобщенные операции, а после приведения типа из абстрактного компонента к конкретному - можно работать с конкретным. Компьютер можно также представить как составной компонент (например DesktopStation:ComputerComponentBase). Можно реализовать поднобное не через интерфейсы, а например через дженерики. Ну там уже сами фантазируйте как вам удобней )

Код

public class ComponentVendor
        {
            public ComponentVendor(string name)
            {
                Name = name;
            }

            public string Name { get; set; } 
        }

        public interface IComputerComponent
        {
            ComponentVendor Vendor { get; }

            IEnumerable<IComputerComponent> Parts { get; }

            bool IsCompatibleWith(IComputerComponent component);

            bool IsCanBeHooked(IComputerComponent component);
            void HookUp(IComputerComponent component);
        }

        public abstract class ComputerComponentBase : IComputerComponent
        {
            private readonly List<IComputerComponent> _parts;

            protected ComputerComponentBase(string vendorName, List<IComputerComponent> parts)
            {
                _parts = parts;
                Vendor = new ComponentVendor(vendorName);
            }

            public ComponentVendor Vendor { get; private set; }

            public IEnumerable<IComputerComponent> Parts { get { return _parts; } }

            public abstract bool IsCompatibleWith(IComputerComponent component);

            public virtual bool IsCanBeHooked(IComputerComponent component)
            {
                return 
                    !_parts.Contains(component) && 
                    IsCompatibleWith(component);
            }

            public virtual void HookUp(IComputerComponent component)
            {
                if (IsCanBeHooked(component))
                {
                    _parts.Add(component);
                }
            }
        }

        public class Monitor : ComputerComponentBase
        {
            public double Diagonal { get; set; }

            public Monitor(string vendorName, double diagonal)
                :base(vendorName, new List<IComputerComponent>())
            {
                Diagonal = diagonal;
            }

            public override bool IsCompatibleWith(IComputerComponent component)
            {
                //Выясняем реальный тип аргумента и решаем - совместим ли он с нашим монитором.
                throw new NotImplementedException();
            }
        }

        public class SystemBlock : ComputerComponentBase
        {
            public SystemBlock(string vendorName)
                : base(vendorName, new List<IComputerComponent>())
            {
                //Do nothing
            }

            public override bool IsCompatibleWith(IComputerComponent component)
            {
                //Выясняем реальный тип аргумента и решаем - совместим ли он с нашим
                //системным блоком. Для этого нужно позырить в другие компоненты блока, 
                //и например узнать - совместима ли карта памяти с текущей 
                //уже подключенной материнкой и т.д.
                throw new NotImplementedException();
            }
        }

Автор: Retamon 25.9.2013, 11:49
Всем спасибо за советы. Но что-то вы не то мне советуете.
Мне нужно хранить данные, а вы предлагаете классами мне зашить их намертво в код.
Каждый раз если что-то добавилось - дописывать код?

Нашел вроде
http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html

Придется создать БД и забить всю иерахию.

Автор: dzaraev 25.9.2013, 15:07
Цитата(Retamon @  25.9.2013,  11:49 Найти цитируемый пост)
Мне нужно хранить данные, а вы предлагаете классами мне зашить их намертво в код.

Каков вопрос - таков ответ  smile 

Цитата(Retamon @  24.9.2013,  15:42 Найти цитируемый пост)
Нужно написать программу, помогите выбрать для нее структуру данных.

Структура данных может быть описана и в коде, и абстрактно и черт знает как еще. Ваш вопрос должен был быть таким: "как строить реляционную модель данных, когда данные представляют иерархию" или как-то так. 
И кстати вам всё равно придётся 
Код

классами мне зашить их намертво в код.

если не классами, так запросами (string или linq) т.к. на уровне кода вам также потреуется модель данных и если изменится реляционная схема - изменится и объектная модель (хоть и не в 100% случаев).

Автор: k0rvin 1.10.2013, 18:30
Цитата(dzaraev @  25.9.2013,  15:07 Найти цитируемый пост)
Каков вопрос - таков ответ

Вопрос, кстати, достаточно нормальный, хотя немного двусмысленный. В любом случае, при чем тут ООАиП, классы и паттерны — не понятно.

Цитата(Retamon @  24.9.2013,  15:42 Найти цитируемый пост)
Нужно написать программу, помогите выбрать для нее структуру данных.

Двусвязный граф (bidirectional graph).

Цитата(Retamon @  24.9.2013,  15:42 Найти цитируемый пост)
и книжку или ссылку, куда что читать

Для начала: http://en.wikibooks.org/wiki/Data_Structures/Graphs
Пример реализации: http://quickgraph.codeplex.com/SourceControl/latest#3.0/sources/QuickGraph/BidirectionalGraph.cs умеет также сериализацию, т.е. можно просто сохранять в файл при завершении работы программы, например. Однако, если предполагается, что в будущем БД комплектующих разрастется, то, конечно, стоит задуматься об использовании СУБД. ИМХО, лучше всего тут подойдут http://en.wikipedia.org/wiki/Graph_database нежели реляционные СУБД.

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