Программа "Поисковая система на основе хэш-таблиц"

 

Оглавление


Введение

1.Постановка задачи

.Краткая теория

2.1Основные методы объектно-ориентированного программирования

.2Принцип сохраняемости

.3Паттерны проектирования

3.Ход выполнения

3.1Выбор языка программирования и среды разработки приложения

.2Реализация основных принципов ООП

.3Реализация паттерна

.4Использование принципа сохраняемости

.5Описание пользовательского интерфейса

Заключение

Список литературы

Приложение А. Листинг программы

Введение


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


1.Постановка задачи


Реализовать программу «Поисковая система на основе хэш-таблиц».

Программа должна иметь графический пользовательский интерфейс. Языки программирования - C++, C#, Java, PHP5.

Обязательные требования:

использование методов объектно-ориентированного программирования (минимум 2 основных «кита»);

использование принципа сохраняемости;

применение минимум одного паттерна проектирования.


.Краткая теория


3.1Основные методы объектно-ориентированного программирования


Абстракция - в объектно-ориентированном программировании это придание объекту характеристик, которые отличают его от всех других объектов, четко определяя его концептуальные границы. Основная идея состоит в том, чтобы отделить способ использования составных объектов данных от деталей их реализации в виде более простых объектов, подобно тому, как функциональная абстракция разделяет способ использования функции и деталей её реализации в терминах более примитивных функций. Таким образом, данные обрабатываются функцией высокого уровня с помощью вызова функций низкого уровня. Такой подход является основой объектно-ориентированного программирования. Это позволяет работать с объектами, не вдаваясь в особенности их реализации. В каждом конкретном случае применяется тот или иной подход: инкапсуляция, полиморфизм или наследование. Например, при необходимости обратиться к скрытым данным объекта, следует воспользоваться инкапсуляцией, создав, так называемую, функцию доступа или свойство. Абстракция данных - популярная и в общем неверно определяемая техника программирования. Фундаментальная идея состоит в разделении несущественных деталей реализации подпрограммы и характеристик, существенных для корректного ее использования. Такое разделение может быть выражено через специальный «интерфейс», сосредотачивающий описание всех возможных применений программы. С точки зрения теории множеств, процесс представляет собой организацию для группы подмножеств своего множества. См. также Закон обратного отношения между содержанием и объемом понятия.

Инкапсуляция - свойство языка программирования, позволяющее пользователю не задумываться о сложности реализации используемого программного компонента (что у него внутри?), а взаимодействовать с ним посредством предоставляемого интерфейса (публичных методов и членов), а также объединить и защитить жизненно важные для компонента данные. При этом пользователю предоставляется только спецификация (интерфейс) объекта. Пользователь может взаимодействовать с объектом только через этот интерфейс. Реализуется с помощью ключевого слова: public. Пользователь не может использовать закрытые данные и методы. Реализуется с помощью ключевых слов: private, protected, internal. Инкапсуляция - один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с абстракцией, полиморфизмом и наследованием). Сокрытие реализации целесообразно применять в следующих случаях: предельная локализация изменений при необходимости таких изменений, прогнозируемость изменений (какие изменения в коде надо сделать для заданного изменения функциональности) и прогнозируемость последствий изменений.

Наследование - один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с инкапсуляцией, полиморфизмом и абстракцией), позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом. Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса. Простое наследование Класс, от которого произошло наследование, называется базовым или родительским (англ. base class). Классы, которые произошли от базового, называются потомками, наследниками или производными классами (англ. derived class). В некоторых языках используются абстрактные классы.

Абстрактный класс - это класс, содержащий хотя бы один абстрактный метод, он описан в программе, имеет поля, методы и не может использоваться для непосредственного создания объекта. То есть от абстрактного класса можно только наследовать. Объекты создаются только на основе производных классов, наследованных от абстрактного. Например, абстрактным классом может быть базовый класс «сотрудник вуза», от которого наследуются классы «аспирант», «профессор» и т. д. Так как производные классы имеют общие поля и функции (например, поле «год рождения»), то эти члены класса могут быть описаны в базовом классе. В программе создаются объекты на основе классов «аспирант», «профессор», но нет смысла создавать объект на основе класса «сотрудник вуза».

Множественное наследование

При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование реализовано в C++. Из других языков, предоставляющих эту возможность, можно отметить Python и Эйфель. Множественное наследование поддерживается в языке UML. Множественное наследование - потенциальный источник ошибок, которые могут возникнуть из-за наличия одинаковых имен методов в предках. В языках, которые позиционируются как наследники C++ (Java, C# и др.), от множественного наследования было решено отказаться в пользу интерфейсов. Практически всегда можно обойтись без использования данного механизма. Однако, если такая необходимость все-таки возникла, то, для разрешения конфликтов использования наследованных методов с одинаковыми именами, возможно, например, применить операцию расширения видимости - «::» - для вызова конкретного метода конкретного родителя. Попытка решения проблемы наличия одинаковых имен методов в предках была предпринята в языке Эйфель, в котором при описании нового класса необходимо явно указывать импортируемые члены каждого из наследуемых классов и их именование в дочернем классе. Большинство современных объектно-ориентированных языков программирования (C#, Java, Delphi и др.) поддерживают возможность одновременно наследоваться от класса-предка и реализовать методы нескольких интерфейсов одним и тем же классом. Этот механизм позволяет во многом заменить множественное наследование - методы интерфейсов необходимо переопределять явно, что исключает ошибки при наследовании функциональности одинаковых методов различных классов-предков.

Полиморфизм - возможность объектов с одинаковой спецификацией иметь различную реализацию. Язык программирования поддерживает полиморфизм, если классы с одинаковой спецификацией могут иметь различную реализацию - например, реализация класса может быть изменена в процессе наследования. Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». Полиморфизм - один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с абстракцией, инкапсуляцией и наследованием). Полиморфизм позволяет писать более абстрактные программы и повысить коэффициент повторного использования кода. Общие свойства объектов объединяются в систему, которую могут называть по-разному - интерфейс, класс. Общность имеет внешнее и внутреннее выражение: внешняя общность проявляется как одинаковый набор методов с одинаковыми именами и сигнатурами (именем методов и типами аргументов и их количеством); внутренняя общность - одинаковая функциональность методов. Её можно описать интуитивно или выразить в виде строгих законов, правил, которым должны подчиняться методы. Возможность приписывать разную функциональность одному методу (функции, операции) называется перегрузкой метода (перегрузкой функций, перегрузкой операций).

Формы полиморфизма

Полиморфизм включения

Этот полиморфизм называют чистым полиморфизмом. Применяя такую форму полиморфизма, родственные объекты можно использовать обобщенно. С помощью замещения и полиморфизма включения можно написать один метод для работы со всеми типами объектов TPerson. Используя полиморфизм включения и замещения можно работать с любым объектом, который проходит тест «is-A». Полиморфизм включения упрощает работу по добавлению к программе новых подтипов, так как не нужно добавлять конкретный метод для каждого нового типа, можно использовать уже существующий, только изменив в нем поведение системы. С помощью полиморфизма можно повторно использовать базовый класс; использовать любого потомка или методы, которые использует базовый класс.

Параметрический полиморфизм

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

Параметрические методы. Если полиморфизм включения влияет на наше восприятие объекта, то параметрические полиморфизм влияет на используемые методы, так как можно создавать методы родственных классов, откладывая объявление типов до времени выполнения. Во избежание написания отдельного метода каждого типа применяется параметрический полиморфизм, при этом тип параметров будет являться таким же параметром, как и операнды.

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

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


3.1Принцип сохраняемости


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

Любой программный объект существует в памяти и живет во времени. Спектр сохраняемости объектов охватывает:

·Промежуточные результаты вычисления выражений.

·Локальные переменные в вызове процедур.

·Собственные (статические) переменные функции, глобальные переменные и динамически создаваемые данные.

·Данные, сохраняющиеся между сеансами выполнения программы.

·Данные, сохраняемые при переходе на новую версию программы.

·Данные, которые вообще переживают программу.

Традиционно, первыми тремя уровнями занимаются языки программирования, а последними - базы данных. Языки программирования, как правило, не поддерживают сохраняемость в полном объеме. Введение сохраняемости, как нормальной составной части объектного подхода приводит к объектно-ориентированным базам данных (OODB). На практике подобные базы данных строятся на основе проверенных временем моделей - последовательных, индексированных, иерархических, сетевых или реляционных, но программист может ввести абстракцию объектно-ориентированного интерфейса, через который запросы к базе данных и другие операции выполняются в терминах объектов, время жизни которых превосходит время жизни отдельной программы. При использовании одноуровневой памяти как в System/38 разработка OODB существенно упрощается.

Сохраняемость - это не только проблема сохранения данных. В OODB имеет смысл сохранять и классы, так, чтобы программы могли правильно интерпретировать данные. Это создает большие трудности по мере увеличения объема данных, особенно, если класс объекта вдруг потребовалось изменить.

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

программирование поисковая система

3.1Паттерны проектирования


Что такое паттерн проектирования?

По словам Кристофера Александра, «любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип ее решения, причем таким образом, что это решение можно потом использовать миллион раз, ничего не изобретая заново». Хотя Александр имел в виду паттерны, возникающие при проектировании зданий и городов, но его слова верны и в отношении паттернов объектно-ориентированного проектирования. Наши решения выражаются в терминах объектов и интерфейсов, а не стен и дверей, но в обоих случаях смысл паттерна - предложить решение определенной задачи в конкретном контексте.

В общем случае паттерн состоит из четырех основных элементов:

)Имя

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

)Задача

Описание того, когда следует применять паттерн. Необходимо сформулировать задачу и ее контекст. Может описываться конкретная проблема проектирования, например способ представления алгоритмов в виде объектов. Иногда отмечается, какие структуры классов или объектов свидетельствуют о негибком дизайне. Также может включаться перечень условий, при выполнении которых имеет смысл применять данный паттерн.

)Решение

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

)Результаты

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

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

Паттерны проектирования - это не то же самое, что связанные списки или хеш-таблицы, которые можно реализовать в виде класса и повторно использовать без каких бы то ни было модификаций. Но это и не сложные, предметно-ориентированные решения для целого приложения или подсистемы. Здесь под паттернами проектирования понимается описание взаимодействия объектов и классов, адаптированных для решения общей задачи проектирования в конкретном контексте.

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

Хотя, строго говоря, паттерны используются в проектировании, они основаны на практических решениях, реализованных на основных языках объектно-ориентированного программирования типа Smalltalk и C++, C#, Java, а не на процедурных (Pascal, С, Ada и т.п.) или объектно-ориентированных языках с динамической типизацией (CLOS, Dylan, Self).

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

Как описываются паттерны проектирования?

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

При описании паттернов проектировании придерживаются единого принципа. Описание каждого паттерна разбито на разделы, перечисленные ниже.

Такой подход позволяет единообразно представить информацию, облегчает изучение, сравнение и применение паттернов.

Название и классификация паттерна

Название паттерна должно четко отражать его назначение.

Классифицируются паттерны по назначению и уровню применения:

по уровню применения паттерны делятся на применяемые к объектам и применяемые к классам.

по назначению паттерны делятся на порождающие, структурные и паттерны поведения.

Назначение

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

Известен также под именем

Другие распространенные названия паттерна, если таковые имеются.

Мотивация

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

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

Структура

Графическое представление классов в паттерне с использованием нотации, основанной на методике Object Modeling Technique (OMT). Можно пользоваться также диаграммами взаимодействий для иллюстрации последовательностей запросов и отношений между объектами.

Участники

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

Отношения

Взаимодействие участников для выполнения своих функций.

Результаты

Насколько паттерн удовлетворяет поставленным требованиям? Результаты применения, компромиссы, на которые приходится идти. Какие аспекты поведения системы можно независимо изменять, используя данный паттерн?

Реализация

Сложности и так называемые подводные камни при реализации паттерна. Советы и рекомендуемые приемы. Есть ли у данного паттерна зависимость от языка программирования?

Пример кода

Фрагмент кода, иллюстрирующий вероятную реализацию паттерна.

Известные применения

Возможности применения паттерна в реальных системах. Даются, по меньшей мере, два примера из различных областей.

Родственные паттерны

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

.Ход выполнения


3.1Выбор языка программирования и среды разработки приложения


В качестве средств разработки приложения мною были выбраны среда разработки Microsoft Visual Studio и язык программирования C#.Visual Studio - линейка продуктов компании Microsoft, включающих интегрированную среду разработки программного обеспечения на языках C#, C++ VisualBasic и др., а так же ряд других инструментальных средств.

Данные продукты позволяют разрабатывать как консольные приложения, так и приложения с графическим интерфейсом, в том числе с поддержкой технологии Windows Forms, а также веб-сайты, веб-приложения, веб-службы как в родном, так и в управляемом кодах для всех платформ, поддерживаемых Microsoft Windows, Windows Mobile, Windows CE,.NET Framework, Xbox, Windows Phone.NET Compact Framework и Microsoft Silverlight.Visual Studio включает в себя редактор исходного кода с поддержкой технологии IntelliSense и возможностью простейшего рефакторинга кода. Встроенный отладчик может работать как отладчик уровня исходного кода, так и как отладчик машинного уровня. Остальные встраиваемые инструменты включают в себя редактор форм для упрощения создания графического интерфейса приложения, веб-редактор, дизайнер классов и дизайнер схемы базы данных. Visual Studio позволяет создавать и подключать сторонние дополнения (плагины) для расширения функциональности практически на каждом уровне, включая добавление поддержки систем контроля версий исходного кода (как например, Subversion и Visual SourceSafe), добавление новых наборов инструментов (например, для редактирования и визуального проектирования кода на предметно-ориентированных языках программирования или инструментов для прочих аспектов процесса разработки программного обеспечения (например, клиент Team Explorer для работы с Team Foundation Server).

Мною были выбраны среда разработки Microsoft Visual Studio и язык программирования C#, так как считаю, что в совокупности они представляют собой наиболее мощный и удобный инструмент для разработки и отладки приложений под платформу Microsoft Windows.


3.2 Реализация основных принципов ООП


При разработке программного продукта мною были использованы два принципа объектно-ориентированного программирования - инкапсуляция и полиморфизм.

Инкапсуляция

Переменная «PATH» хранит полный путь до XML-файла, в который записываются данные из хеш-таблицы. При задании значения свойства «XMLPATH» производится проверка, существует ли файл по указанному пути. Если файл не существует, то он создается, в файл записывается информация о версии XML и кодировке, а также записывается корневой элемент с необходимыми атрибутами. После этого значение передается переменной «PATH».


Программная реализация свойства:

private static string PATH = "";

/// <summary>

/// Возвращает или задает имя файла для загрузки и сохранения XML.

/// </summary>static string XMLPATH

{{ return main_form.PATH; }

{(!File.Exists(value))

{writer = new XmlTextWriter(File.Create(value), Encoding.UTF8);.WriteStartDocument();.WriteStartElement("hashtable");.WriteStartAttribute("pair_count");.WriteEndAttribute();.WriteEndElement();.Close();

}_form.PATH = value;

}

}


Полиморфизм

В программе реализован интерфейс «IModify», определяющий имена и сигнатуры методов, реализованных в классе «StringModificator».


Программная реализация интерфейса и реализующего его класса

public interface IModify

{

/// <summary>

/// Производит в строке замену BB-тегов на коды RTF.

/// </summary>

/// <returns>Возвращает измененную строку.</returns>Modify();

}class StringModificator: IModify

{static string TEXT;

StringModificator(string text)

{= text;

}

/// <summary>

/// Производит в строке замену BB-тегов на коды RTF.

/// </summary>

/// <returns>Возвращает измененную строку.</returns>string Modify()

{= string.Concat("{\\rtf1\\ansi\\ansicpg1251\r\n", TEXT);= TEXT.Replace("[b]", "{\\b ").Replace("[/b]", "}");= TEXT.Replace("[u]", "{\\ul ").Replace("[/u]", "}");= TEXT.Replace("[i]", "{\\i ").Replace("[/i]", "}");= TEXT.Replace("\r\n", "\\par ");= string.Concat(TEXT, "\r\n}");TEXT;

}

}


3.3 Реализация паттерна


Паттерн «Модификатор», реализуемый с помощью класса «StringModificator», предназначен для изменения строковых объектов, выполнения их преобразования и форматирования текста перед выводом на экран в поле форматированного текста.

Программная реализация паттерна:

public class StringModificator: IModify

{static string TEXT;StringModificator(string text)

{= text;

}

/// <summary>

/// Производит в строке замену BB-тегов на коды RTF.

/// </summary>

/// <returns>Возвращает измененную строку.</returns>string Modify()

{= string.Concat("{\\rtf1\\ansi\\ansicpg1251\r\n", TEXT);= TEXT.Replace("[b]", "{\\b ").Replace("[/b]", "}");= TEXT.Replace("[u]", "{\\ul ").Replace("[/u]", "}");= TEXT.Replace("[i]", "{\\i ").Replace("[/i]", "}");= TEXT.Replace("\r\n", "\\par ");= string.Concat(TEXT, "\r\n}");TEXT;

}

}


3.4 Использование принципа сохраняемости


Для хранения данных программы я выбрал формат XML (eXtensible Markup Language) в связи с рядом его преимуществ над другими способами хранения данных, в рамках поставленной задачи.широко используется для создания баз данных. В документе XML используется древовидная структура хранения данных. Хотя по большому счету хранение данных в виде документов XML не слишком эффективно, у такого способа хранения есть свои преимущества. Как и в отношении передачи сообщений, самым большим преимуществом является простота. Древовидная структура - интуитивно понятный и знакомый способ организации данных. Кроме того, почти любой тип древовидной структуры - от реляционных баз данных до объектно-ориентированных баз данных и иерархических структур - может быть представлен с помощью дерева данных XML. Другое существенное преимущество использования XML для хранения данных заключается в том, что XML поддерживает набор символов Unicode. Следовательно, любой символ любого алфавита мира можно включить в документы XML на «законном основании».

Для осуществления взаимодействия с XML я использовал стандартные средства работы с XML-документами языка программирования C# - такие классы как: XmlDocument, XmlNodeList, XmlTextWriter, XmlElement, XmlAttribute, XmlNode и др.


Фрагмент кода программы, демонстрирующий создание XML-документа, содержащего информацию о версии XML, кодировке, а также корневой элемент с необходимыми атрибутами:

XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8);.WriteStartDocument();.WriteStartElement("hashtable");.WriteStartAttribute("pair_count");.WriteEndAttribute();.WriteEndElement();.Close();


3.5 Описание пользовательского интерфейса


Интерфейс программы построен с использованием стандартных компонентов Windows Forms. На рис. 4.5.1 изображена главная форма программы.


Рисунок 4.5.1 Главная форма программы


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


Рисунок 4.5.2 Демонстрация поиска по ключевому слову

После выбора нужной статьи стрелками вверх/вниз и нажатия клавиши «ввод», в нижней части формы отображается соответствующая ключу статья (рис. 4.5.3).


Рисунок 4.5.3 Отображение статьи по выбранному ключу


После запуска программы, хеш-таблица в ее основании не заполнена данными. Эти данные можно загрузить из XML-файла, выбрав в меню «Файл» ? «Загрузить из XML…» (рис. 4.5.4).


Рисунок 4.5.4 Загрузка/сохранение XML из меню «Файл»

Так же можно добавить статью вручную. При выборе в меню пункта «Добавить статью…» появляется форма добавления статьи (рис. 4.5.5).


Рисунок 4.5.5


После добавления статьи данные сохраняются в открытом в данный момент XML-файле.

Выбрав пункт меню «Файл» ? «Сохранить в XML…» можно сохранить данные программы, указав путь к XML-файлу.


Заключение


Приложение было разработано в соответствии с поставленными заданиями. Программа была написана на языке C# в среде программирования Microsoft Visual Studio 2010. Мною были реализованы два из четырех основных «кита», реализована запись и чтение данных XML, а так же разработан паттерн «Модификатор», выполняющий изменения строковых объектов, их преобразование и форматирование текста.


Список литературы


1.Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. П75 «Приемы объектно-ориентированного проектирования. Паттерны проектирования» - СПб: Питер, 2001. - 368 с.: ил. (Серия «Библиотека программиста»);

.Лекции по дисциплине «Объектно-ориентированное программирование», предодаватель: доцент каф. ПОВТ Бузало Г.А.

.Шилдг, Герберт «Полный справочник по C#». Перевод с английского - М.: Издательский дом "Вильяме", 2004. - 752 с.

.Библиотека MSDN - #"justify">Приложение А. Листинг программы


Файл main_form.cs

using System;

using System.Collections;

using System.Collections.Generic;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.Windows.Forms;

using System.Xml;

using System.Text;


namespace HashSearchEngine

{

public partial class main_form : Form

{

public interface IModify

{

/// <summary>

/// Производит в строке замену BB-тегов на коды RTF.

/// </summary>

/// <returns>Возвращает измененную строку.</returns>

string Modify();

}

public class StringModificator : IModify

{

private static string TEXT;


public StringModificator(string text)

{

TEXT = text;

}


/// <summary>

/// Производит в строке замену BB-тегов на коды RTF.

/// </summary>

/// <returns>Возвращает измененную строку.</returns>

public string Modify()

{

TEXT = string.Concat("{\\rtf1\\ansi\\ansicpg1251\r\n", TEXT);

TEXT = TEXT.Replace("[b]", "{\\b ").Replace("[/b]", "}");

TEXT = TEXT.Replace("[u]", "{\\ul ").Replace("[/u]", "}");

TEXT = TEXT.Replace("[i]", "{\\i ").Replace("[/i]", "}");

TEXT = TEXT.Replace("\r\n", "\\par ");

TEXT = string.Concat(TEXT, "\r\n}");


return TEXT;

}

}


private static string SEARCH_BOX_DEFTEXT;

private static string MAINFORM_HEAD_TEXT;

private static ListBox listbox = new ListBox();

private static Hashtable HASH = new Hashtable();

public static Hashtable GETHASH

{

get { return main_form.HASH; }

}

private static string PATH = "";

/// <summary>

/// Возвращает или задает имя файла для загрузки и сохранения XML.

/// </summary>

public static string XMLPATH

{

get { return main_form.PATH; }

set

{

if (value != "")

if (!File.Exists(value))

{

XmlTextWriter writer = new XmlTextWriter(File.Create(value), Encoding.UTF8);

writer.WriteStartDocument();

writer.WriteStartElement("hashtable");

writer.WriteStartAttribute("pair_count");

writer.WriteEndAttribute();

writer.WriteEndElement();

writer.Close();

}


main_form.PATH = value;

}

}


private void GetAllNodes(ToolStripDropDownButton dropdown)

{

dropdown.DropDownItems.Clear();


foreach (object O in HASH.Keys)

{

dropdown.DropDownItems.Add(O.ToString());

}


if (dropdown.DropDownItems.Count > 0)

dropdown.Enabled = true;

}

public static void LoadXML(string path)

{

XmlDocument document = new XmlDocument();

FileStream stream = new FileStream(path, FileMode.Open);

try

{

document.Load(stream);

stream.Close();

}

catch (XmlException)

{

stream.Close();


XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8);

writer.WriteStartDocument();

writer.WriteStartElement("hashtable");

writer.WriteStartAttribute("pair_count");

writer.WriteEndAttribute();

writer.WriteEndElement();

writer.Close();


stream = new FileStream(path, FileMode.Open);

document.Load(stream);

stream.Close();

}


XmlNodeList list = document.GetElementsByTagName("pair");

if (list.Count > 0) HASH.Clear();


for (int i = 0; i < list.Count; i++)

{

HASH.Add(list[i].ChildNodes[0].InnerText, list[i].ChildNodes[1].InnerText);

}

}

public static void SaveXML(string path)

{

object[] keys = new object[HASH.Count];

HASH.Keys.CopyTo(keys, 0);


XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8);

writer.WriteStartDocument();

writer.WriteStartElement("hashtable");

writer.WriteStartAttribute("pair_count");

writer.WriteEndAttribute();

writer.WriteEndElement();

writer.Close();


XmlDocument document = new XmlDocument();

document.Load(path);



for (int i = 0; i < HASH.Count; i++)

{

XmlElement pair = document.CreateElement("pair");

XmlAttribute pair_id = document.CreateAttribute("id");

pair_id.Value = (i + 1).ToString();

pair.Attributes.Append(pair_id);


XmlElement key = document.CreateElement("key");

key.InnerText = keys[i].ToString();

pair.AppendChild(key);


XmlElement value = document.CreateElement("value");

value.InnerText = HASH[keys[i]].ToString();

pair.AppendChild(value);


document.DocumentElement.AppendChild(pair);

}


if (document.DocumentElement.HasChildNodes)

document.DocumentElement.Attributes["pair_count"].Value = document.DocumentElement.ChildNodes.Count.ToString();


document.Save(path);

}

public static string AddXMLNode(string add_key, string add_value)

{

try

{

HASH.Add(add_key, add_value);

}

catch (ArgumentException)

{

return "Статья не добавлена:\r\nКлюч уже присутствует в Хеш-таблице";

}

catch (Exception err)

{

return "Статья не добавлена\r\nСообщение:\r\n" + err.Message;

}


if (!File.Exists(XMLPATH))

{

XmlTextWriter writer = new XmlTextWriter(XMLPATH, Encoding.UTF8);

writer.WriteStartDocument();

writer.WriteStartElement("hashtable");

writer.WriteStartAttribute("pair_count");

writer.WriteEndAttribute();

writer.WriteEndElement();

writer.Close();

}


XmlDocument document = new XmlDocument();

document.Load(XMLPATH);


XmlElement pair = document.CreateElement("pair");

XmlAttribute pair_id = document.CreateAttribute("id");


int last_child_id = 0;

try

{

int.TryParse(document.DocumentElement.LastChild.Attributes["id"].Value, out last_child_id);

}

catch (NullReferenceException)

{

last_child_id = 0;

}

catch (Exception) { }


pair_id.Value = (last_child_id + 1).ToString();

pair.Attributes.Append(pair_id);


XmlElement key = document.CreateElement("key");

key.InnerText = add_key;

pair.AppendChild(key);


XmlElement value = document.CreateElement("value");

value.InnerText = add_value;

pair.AppendChild(value);


document.DocumentElement.AppendChild(pair);


if (document.DocumentElement.HasChildNodes)

document.DocumentElement.Attributes["pair_count"].Value = document.DocumentElement.ChildNodes.Count.ToString();


document.Save(XMLPATH);


return "Статья успешно добавлена";

}


public main_form()

{

InitializeComponent();


listbox.Size = new Size(search_text.Width, 0);

listbox.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);

listbox.Font = search_text.Font;

listbox.Parent = listbox_panel;

listbox_panel.Hide();

SEARCH_BOX_DEFTEXT = search_text.Text;

MAINFORM_HEAD_TEXT = this.Text;

}


private void main_form_Load(object sender, EventArgs e)

{

listbox.MouseClick += new MouseEventHandler(listbox_MouseClick);


allNodes_toolStripDropDownButton.Enabled = false;

allNodes_toolStripDropDownButton.DropDownItems.Clear();

}


#region События MenuStrip

// **************************************************************************

private void выходToolStripMenuItem_Click(object sender, EventArgs e)

{

Application.Exit();

}


private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)

{

about_form_RamGec about = new about_form_RamGec();

about.ShowDialog();

}


private void добавитьстатьюToolStripMenuItem_Click(object sender, EventArgs e)

{

if (XMLPATH == "")

{

OpenFileDialog file_path = new OpenFileDialog();

file_path.Filter = "XML-документ (*.xml)|*.xml";


if (file_path.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

XMLPATH = file_path.FileName;

LoadXML(file_path.FileName);

GetAllNodes(allNodes_toolStripDropDownButton);

}

else

{

MessageBox.Show(

this,

"Необходимо указать путь к XML-файлу.",

"Предупреждение",

MessageBoxButtons.OK,

MessageBoxIcon.Exclamation

);

return;

}

}



add_form add = new add_form();

if (add.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

GetAllNodes(allNodes_toolStripDropDownButton);

}

}


private void сохранитьXMLToolStripMenuItem_Click(object sender, EventArgs e)

{

SaveFileDialog save_path = new SaveFileDialog();

save_path.AddExtension = true;

save_path.DefaultExt = "xml";

save_path.Filter = "XML-документ (*.xml)|*.xml";

if (save_path.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

XMLPATH = save_path.FileName;

SaveXML(save_path.FileName);

this.Text = MAINFORM_HEAD_TEXT + " - " + save_path.FileName.Remove(0, save_path.FileName.LastIndexOf('\\') + 1);

}

}


private void загрузитьИзXMLToolStripMenuItem_Click(object sender, EventArgs e)

{

OpenFileDialog file_path = new OpenFileDialog();

file_path.Filter = "XML-документ (*.xml)|*.xml";

if (file_path.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

XMLPATH = file_path.FileName;

LoadXML(file_path.FileName);

GetAllNodes(allNodes_toolStripDropDownButton);

this.Text = MAINFORM_HEAD_TEXT + " - " + file_path.SafeFileName;

}

}


private void очиститьХештаблицуToolStripMenuItem_Click(object sender, EventArgs e)

{

HASH.Clear();

if(!search_text.Focused) search_text.Text = SEARCH_BOX_DEFTEXT;

out_richText.Clear();

XMLPATH = "";

this.Text = MAINFORM_HEAD_TEXT;

allNodes_toolStripDropDownButton.Enabled = false;

}


// **************************************************************************

#endregion


private void search_button_Click(object sender, EventArgs e)

{

if (HASH.ContainsKey(search_text.Text))

{

out_richText.Rtf = new StringModificator((string)HASH[search_text.Text]).Modify();

}

}


private void out_richText_LinkClicked(object sender, LinkClickedEventArgs e)

{

Process.Start(e.LinkText);

}


private void search_text_TextChanged(object sender, EventArgs e)

{

if (HASH.Count == 0) return;


listbox.Items.Clear();


if (search_text.Text != "" && search_text.Text != SEARCH_BOX_DEFTEXT)

{

int height = 0, count = 0;

foreach (object O in HASH.Keys)

{

if (O.ToString().ToLower().IndexOf(search_text.Text.ToLower()) >= 0)

{

if (++count > 5) break;

listbox.Items.Add(O);

height += 25;

}

}


listbox.Size = new Size(listbox.Size.Width, height);

if (listbox.Items.Count > 0)

{

listbox_panel.Show();

listbox.SelectedItem = listbox.Items[0];

}

else

{

listbox_panel.Hide();

}

}

else

{

listbox_panel.Hide();

}

}


private void search_text_SizeChanged(object sender, EventArgs e)

{

listbox.Size = new Size(search_text.Size.Width, listbox.Size.Height);

}


private void search_text_Enter(object sender, EventArgs e)

{

if (search_text.Text == SEARCH_BOX_DEFTEXT)

{

search_text.Text = "";

}

search_text.ForeColor = Color.Black;

}


private void search_text_Leave(object sender, EventArgs e)

{

if (search_text.Text == "")

{

search_text.Text = SEARCH_BOX_DEFTEXT;

}

search_text.ForeColor = Color.Gray;

}


private void search_text_KeyDown(object sender, KeyEventArgs e)

{

if (HASH.Count == 0 || listbox.Items.Count == 0) return;


if (e.KeyCode == Keys.Down)

{

if (listbox.SelectedIndex < listbox.Items.Count - 1)

listbox.SelectedIndex = listbox.SelectedIndex + 1;

}

if (e.KeyCode == Keys.Up)

{

if (listbox.SelectedIndex != 0)

listbox.SelectedIndex = listbox.SelectedIndex - 1;

}

if (e.KeyCode == Keys.Enter)

{

search_text.Text = listbox.SelectedItem.ToString();

search_button_Click(sender, e);

out_richText.Focus();

listbox_panel.Hide();

}

if (e.KeyCode == Keys.Escape)

{

listbox_panel.Hide();

}

}


private void listbox_MouseClick(object sender, MouseEventArgs e)

{

if (HASH.Count == 0 || listbox.Items.Count == 0) return;


search_text.Text = listbox.SelectedItem.ToString();

search_button_Click(sender, e);

out_richText.Focus();

listbox_panel.Hide();

}


private void allNodes_toolStripDropDownButton_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)

{

if (HASH.ContainsKey(e.ClickedItem.Text))

out_richText.Rtf = new StringModificator((string)HASH[e.ClickedItem.Text]).Modify();

}

}

}



Файл add_form.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;


namespace HashSearchEngine

{

public partial class add_form : Form

{

public add_form()

{

InitializeComponent();

}


private void save_button_Click(object sender, EventArgs e)

{

main_form.AddXMLNode(key_text.Text, value_text.Text);

}


private void plus_button_Click(object sender, EventArgs e)

{

main_form.AddXMLNode(key_text.Text, value_text.Text);

key_text.Clear();

value_text.Clear();

toolTip1.Show(

"Статья успешно добавлена",

this,

new Point(this.Size.Width / 2 + 50, this.Size.Height / 2),

5000

);

}


private void cancel_button_Click(object sender, EventArgs e)

{

if (key_text.Text.Length > 0 || value_text.Text.Length > 0)

{

if (MessageBox.Show(

this,

"Несохраненные данные будут потеряны.\n\nЗакрыть форму?",

"Подтверждение",

MessageBoxButtons.YesNo,

MessageBoxIcon.Question,

MessageBoxDefaultButton.Button2

) == System.Windows.Forms.DialogResult.Yes)

this.Close();

}

else

{

this.Close();

}

}


private void add_form_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Escape) cancel_button_Click(sender, e);

}

}

}




Оглавление Введение 1.Постановка задачи .Краткая теория 2.1Основные методы объектно-ориентированного программирования .2Принцип сохраняемости

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ