Объектно-ориентированное программирование

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 16.02.2016
Размер файла 1,7 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Содержание

  • Введение
  • 1. Анализ технического задания
  • 2. Проектирование структуры классов
  • 3. Программная реализация
  • 4. Тестирование
  • 5. Руковдство по програмному продукту
    • 5.1 Руководство программиста
    • 5.2 Руководство администратора
    • 5.3 Руководство пользователя
  • Заключение
  • Список литературы
  • Приложение А. Класс разбора математических функций

Введение

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

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

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

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

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

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

Целью работы является разработка программы «Генератор математических функций». Также целью работы является развитие навыков самостоятельной и творческой работы и закрепление навыков работы на языке С++.

В мире есть множество программных продуктов, позволяющих выполнять задачи по построению графиков, такие как Mathcad, Matlab, Excel. Если требуется решать задачи связанные только с графиками, то программа «Генератор математических функций» использовать предпочтительней, так как он сконцентрирован только на этой проблеме. Также данное приложение имеет простой пользовательский интерфейс, удобный мастер функций, возможность построения нескольких графиков функций.

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

1. Анализ технического задания

В дипломной работе необходимо разработать программу «Генератор математических функций».

Для реализации поставленных задач необходимо:

- Разработать алгоритм ввода математического выражения с помощью мастера функций;

- Разработать алгоритм построения графика по заданному выражению;

- Реализовать возможность сохранения построенного графика в файл;

- Реализовать визуальные компоненты для работы с программой.

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

Данное приложение будет реализовано на мощном и гибком объектно-ориентированном языке программирования С++ [1]. Язык С++ предоставляет все средства для реализации базового и производных классов, а также оптимально использует системные ресурсы, что позволяет сделать приложение не только универсальным, но и не очень требовательным к ресурсам компьютера. Также язык С++ поддерживает платформу .NETFramework, что позволяет использовать приложение на различных персональных и переносных компьютерах, на которых установлена эта платформа.

По сравнению с другими объектно-ориентированными языками С++ обладает несколькими особенностями:

- Полная поддержка принципов инкапсуляции, наследования и полиморфизма;

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

- Согласованный и четко определенный набор базовых типов;

- Возможность переопределения пользователем стандартных типов языка и операторов;

- Автоматическая очистка динамически распределяемой памяти;

- Полная поддержка библиотеки базовых классов .NET Framework наряду с легким доступом к Windows API;

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

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

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

К числу подобных метрик относится:

1. Гибкость, которая аккумулирует ряд свойств:

- Модульность;

- Изменяемость;

- Сопровождаемость;

2. Адаптивность, которая подразумевает:

- Настраиваемость;

- Переносимость;

- Способность к взаимодействию;

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

Исправления программного обеспечения может быть инициировано по следующим причинам:

1. исправление программы с недостаточным уровнем качества;

2. изменение программы для повышения уровня качества;

3. изменение программы для удовлетворения изменения в требованиях.

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

Приложение будет реализовано в среде Microsoft Visual Studio 2010 [2] с использованием технологии Windows Forms [3]. Выбор обусловлен тем, что данная среда максимально совместима с операционной системой Microsoft Windows 7. Также данная среда поддерживает все версии .NETFramework, что позволяет создавать приложения для различных платформ. Microsoft Visual Studio 2010 включает в себя новые функции, позволяющие полностью контролировать и упрощать все этапы разработки приложения, выполнять его отладку и тестирование. Также данная среда разработки позволяет использовать визуальный конструктор, что очень важно для написания приложения. Исходя из вышеперечисленного, программный продукт будет обладать следующими аппаратными требованиями:

- 32-разрядный (x86) или 64-разрядный (x64) процессор с тактовой частотой 1 гигагерц (ГГц) или выше;

- 1 гигабайт (ГБ) (для 32-разрядной системы) или 2 ГБ (для 64-разрядной системы) оперативной памяти (ОЗУ);

- 16 гигабайт (ГБ) (для 32-разрядной системы) или 20 ГБ (для 64-разрядной системы) пространства на жестком диске;

- графическое устройство DirectX 9 с драйвером WDDM версии 1.0 или выше.

Исходя из приведенного анализа, ставятся основные требования к приложению:

1. Удобный пользовательский интерфейс;

2. Обеспечение гибкости программы для добавления новых функций;

3. Надежность программы.

2. Проектирование структуры классов

Программа «Генератор математических функций» имеет следующий алгоритм работы

1. Формируется область для прорисовки с помощью компонента ZedGraph;

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

3. Осуществляется синтаксический анализ строки;

4. Полученное на выходе значение используется для определения координат точек графика;

5. Вывод изображения на экран;

Для формирования области прорисовки графика функций используется компонент ZedGraph.

ZedGraph - это библиотека классов Windows Forms UserControl, предназначенная для построения 2D-линий, гистограмм, графиков произвольных наборов данных. Классы обеспечивают высокую степень гибкости, почти каждый элемент графика может быть изменен пользователем. В то же время, использование классов является простым, так как все значения обеспечиваются по умолчанию для всех аспектов графика.

Для ввода выражения необходим «Мастер функций». Он предоставляет возможность на основе списка исходных математических функций и списка арифметических операций создать требуемое выражение.

Преобразование введенной строки осуществляется с помощью класса Expression, который вычисляет значение математического выражения переданного в виде строки. В строке можно использовать переменную x и у, основные математические функции и операции, а так же определены константы pi и e. Расчёт производится в два этапа: сначала происходит разбор строки, далее осуществляется расчёт значения.

После разбора, значение будет передаваться в компонент ZedGraph, где и производится вычисления точек и построения графика.

Описание алгоритма работы программы показано на рисунке 1.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Рисунок 1 - Описание алгоритма работы программы «Генератор математических функций».

3. Программная реализация

Для реализации визуальных компонентов было создано 2 формы: главная форма приложения, которая осуществляет все основные задачи программы, и производная форма (мастер функций), которая вызывается из главной формы и служит для упрощения ввода математического выражения.

На главной форме находятся:

- Область для построения графика;

- 3 текстовых области для ввода функции;

- Кнопка вызова мастера функций;

- Кнопка построения графиков;

- Кнопка очистки области;

- Кнопка сохранения графика в файл;

- 2 текстовых поля для указания диапазона значений X;

- Кнопка включения и отключения сетки на области построения графика;

- Выход из программы.

Производная форма представляет собой меню с набором доступных функций и действий:

- arccos - Арккосинус

- arcctg - Арккотангенс

- arcsin - Арксинус

- arctg - Арктангенс

- cos - Косинус

- ctg - Котангенс

- sin - Синус

- tg - Тангенс

- ln - Натуральный логарифм

- log - Десятичный логарифм

- sqrt - Квадратный корень

- abs - Модуль

- `+' - Сложение

- `-' - Вычитание

- `*' - Умножение

- `/' -Деление

- `^' - Степень

Также доступны наиболее распространённые константы:

- e= 2.718281828459045

- pi= 3.141592653589793

Область построения графика представляет собой компонент ZedGraph. Для прорисовки области используем функцию Load_Graw.

// Функция преобразования компонента ZedGraph к необходимому виду

public:

void Load_Graw (void)

{

// Получим панель для рисования

ZedGraph::GraphPane ^myPane = zedGraphControl1->GraphPane;

// Очистим список кривых на тот случай, если до этого сигналы уже были нарисованы

myPane->CurveList->Clear();

myPane->GraphObjList->Clear();

//Запрет на самосогласования и выход за установленные границы

myPane->XAxis->Scale->MaxGrace=0;

myPane->XAxis->Scale->MinGrace=0;

myPane->YAxis->Scale->MaxGrace=0;

myPane->YAxis->Scale->MinGrace=0;

// Установим размеры шрифтов для подписей по осям

myPane->XAxis->Title->FontSpec->Size = 14;

myPane->YAxis->Title->FontSpec->Size = 14;

// Установим размеры шрифта для легенды

myPane->Legend->FontSpec->Size = 12;

// Установим размеры шрифта для общего заголовка

myPane->Title->FontSpec->Size = 13;

myPane->Title->FontSpec->FontColor=System::Drawing::Color::Black;

myPane->Title->Text = "Область постороения графиков";

myPane->XAxis->Title->Text = "x";

myPane->YAxis->Title->Text = "y";

//Установка фона панели графиков (не рабочая часть)

myPane->Fill->Color=System::Drawing::Color::LightGray;

//Установка фона панели отображения графиков

myPane->Chart->Fill = gcnew Fill( Color::White, Color::White, 0 );

//Установка границы вывода графиков

myPane->Chart->Border->Color=System::Drawing::Color::Black;

// Устанавливаем интересующий нас интервал по оси X

myPane->XAxis->Scale->Min = -10;

myPane->XAxis->Scale->Max = 10;

//Ручная установка шага оси Х

myPane->XAxis->Scale->MinorStep = 1;

myPane->XAxis->Scale->MajorStep = 1;

// Устанавливаем интересующий нас интервал по оси Y

myPane->YAxis->Scale->Min = -10;

myPane->YAxis->Scale->Max = 10;

//Ручная установка шага оси Y

myPane->YAxis->Scale->MinorStep = 1;

myPane->YAxis->Scale->MajorStep = 1;

//Устанавливаем метки только возле осей!

myPane->XAxis->MajorTic->IsOpposite = false;

myPane->XAxis->MinorTic->IsOpposite = false;

myPane->YAxis->MajorTic->IsOpposite = false;

myPane->YAxis->MinorTic->IsOpposite = false;

//Рисуем сетку по X

myPane->XAxis->MajorGrid->IsVisible=false;

myPane->XAxis->MajorGrid->DashOn=5;

myPane->XAxis->MajorGrid->DashOff=5;

myPane->XAxis->MajorGrid->Color=System::Drawing::Color::Gray;

myPane->XAxis->Color=System::Drawing::Color::Gray;

//Рисуем сетку по Y

myPane->YAxis->MajorGrid->IsVisible=false;

myPane->YAxis->MajorGrid->DashOn=5;

myPane->YAxis->MajorGrid->DashOff=5;

myPane->YAxis->MajorGrid->Color=System::Drawing::Color::Gray;

myPane->YAxis->Color=System::Drawing::Color::Gray;

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

// Добавляем информацию по регистрам вывода точек

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

RollingPointPairList ^list1= gcnew RollingPointPairList (10000);

RollingPointPairList ^list2= gcnew RollingPointPairList (10000);

RollingPointPairList ^list3= gcnew RollingPointPairList (10000);

// Выводим пустые линии графиков на экран

LineItem ^F1Curve = myPane->AddCurve( "Функция f(x)", list1, Color::Blue, SymbolType::None);

LineItem ^F2Curve = myPane->AddCurve( "Функция g(x)", list2, Color::Red, SymbolType::None);

LineItem ^F3Curve = myPane->AddCurve( "Функция h(x)", list3, Color::Green, SymbolType::None);

// Ширина линии

F1Curve->Line->Width=2;

F2Curve->Line->Width=2;

F3Curve->Line->Width=2;

// Задаем что линии гладкии

F1Curve->Line->IsSmooth=true;

F2Curve->Line->IsSmooth=true;

F3Curve->Line->IsSmooth=true;

// Обновлем данные об осях

zedGraphControl1->AxisChange ();

// Обновляем график

zedGraphControl1->Invalidate();

}

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

На первом этапе используем функцию SystemStringToChar, которая преобразовывает введенную строку типа String к строке типа Char.

/ Функция преобразования строки типа String в тип char, так как класс разбора работает только с Сhar

public:

char* SystemStringToChar(System::String^ string)

{

//возвращает значение ввиде Сhar

return (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(string);

}

На втором этапе используем класс разбора Expression, который разбирает строку типа Char и осуществляет расчёт значения.

class Expression

{

private:

struct sintElem {

char lexeme;

double number;

};

double * numArray;

sintElem* walkthroughArray;/*Массив в котором хранятся результаты предразбора строки.

Признаком конца такого массива является walkthroughArray[i].lexeme == 127*/

sintElem* start;/*Хранит ссылку на первый элемент массива walkthroughArray

чтобы восстановить её после исполнения вычислительной части*/

//Функции конструктора. Подробные коментарии указаны в теле функций.

/*Функции хранящиеся в файле ArifmometrSortSigment.

Комплекс функций необходим для сортировки в польскую нотацию*/

void sortPoland (sintElem* );

void recursionMain (sintElem*,short&,short&);

void recursionPlus (sintElem*,short&,short&);

void recursionMult (sintElem*,short&,short&);

void recursionPow (sintElem*,short&,short&);

void recursionUnary(sintElem*,short&,short&);

/*Функции хранящиеся в файле ArifmometrPreparationSigment.

Комплекс функция необходимых для полготовки строки к сортировке в польскую нотацию*/

void sintAdaptation (char* );

double setPoint (double, short );

static char* addMult (char* );

sintElem* setArray (char* );

static void addCode (char* );

static inline bool isNumber(char);

static inline bool isLetter(char);

static inline char* argTest(char*);

static inline bool isUnary(char);

sintElem doIt(char,sintElem);

sintElem doIt(char,sintElem,sintElem);

static bool isOperation(char);

unsigned operatorCount(sintElem*);

void delElements(sintElem*, unsigned);

public:

Expression();

Expression(const Expression&);

Expression(char*);

Expression(const std::string&);

Expression& rebild(const std::string&);

Expression& rebild(const char*);

~Expression(void);

static bool isExp(const std::string&);

static bool isExp(const char*);

//Функции выдающие результат вычисления

double calculate ();

double calculate (double);

double calculate (double,double);

Expression& optimization ();

};

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

// Функция построения графиков

public:

void Graw_Draw (void)

{

// Объявляем переменные, которые указывают диапазон значений X

double min_x = System::Convert::ToDouble(textBox_x1->Text);

double max_x = System::Convert::ToDouble(textBox_x2->Text);

// Построение первого графика

if(textBox11->Text != "")

{

// Преобразование строки типа String к типу Сhar

char *stroka1 = SystemStringToChar(textBox11->Text);

// Получаем линии от графиков

LineItem ^F1Curve=(LineItem ^)zedGraphControl1->GraphPane->CurveList[0];

IPointListEdit ^list1= (IPointListEdit ^) F1Curve->Points;

if(Expression::isExp(stroka1) == true)

{

// Вызов функции, которая разбирает строку типа Сhar, преобразуя ее в математическое выражение

Expression exp(stroka1);

for (double x =min_x; x <= max_x; x = x+0.01)

list1->Add(((double)(x)), exp.calculate(x));

}

else

MessageBox::Show("Не верный ввод даных","Ошибка", MessageBoxButtons::OK);}

Для сохранения графиков используем метод компонента ZedGraph.

// Сохранение графика в файл

zedGraphControl1->SaveAsBitmap ();

Этот метод позволяет сохранить график в файле в следующих форматах: png, gif, jpg, tif, bmp.

4. Тестирование

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

В результате было создано тестирующее приложение (рисунок 2), которое позволяет вводить выражение функции и строить график, а также сохранять график в файле.

Рисунок 2 - Тестирующее приложение. Главное окно.

Рисунок 3 - Тестирующее приложение. Ввод выражения с помощью клавиатуры и построение графика.

Рисунок 4 - Тестирующее приложение. Очистка области построения графика.

Рисунок 5 - Тестирующее приложение. Ввод выражения с помощью мастера функций.

Рисунок 6 - Тестирующее приложение. Построение графиков функций.

Рисунок 7 - Тестирующее приложение. Изменение диапазона значений x. Рисование сетки.

Рисунок 7 - Тестирующее приложение. Сохранение графиков в файле.

Рисунок 8 - Тестирующее приложение. Некорректный ввод выражения.

Рисунок 9 - Тестирующее приложение. Построение прерывных функций.

Рисунок 10 - Тестирующее приложение. Выход из программы.

Результат тестирования: в ходе тестирования программы недостатков, влияющих на правильную работу приложения, не выявлено.

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

Листинг тестирующего приложения предложен в Приложении В.

Данная программа тестировалась на компьютере следующей конфигурации:

1. Процессор Intel(R) Core(TM) i5 CPU

2. ОЗУ 4.00 ГБ

3. ОС Microsoft Windows 7 Ultimate 32-разрядная

5. Руковдство по програмному продукту

5.1 Руководство программиста

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

Все преобразования и вычисления, а также вывод результата на экран осуществляется в главной форме Form1.h. Эта форма включает в себя функцию прорисовки области построения графика, функцию преобразования строки к типу Char, функцию вычисления точек графика и построение его на области.

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

// Добавляем информацию по регистрам вывода точек

RollingPointPairList ^list1= gcnew RollingPointPairList (10000);

RollingPointPairList ^list2= gcnew RollingPointPairList (10000);

RollingPointPairList ^list3= gcnew RollingPointPairList (10000);

// Выводим пустые линии графиков на экран

LineItem ^F1Curve = myPane->AddCurve( "Функция f(x)", list1, Color::Blue, SymbolType::None);

LineItem ^F2Curve = myPane->AddCurve( "Функция g(x)", list2, Color::Red, SymbolType::None);

LineItem ^F3Curve = myPane->AddCurve( "Функция h(x)", list3, Color::Green, SymbolType::None);

Для разбора введенной строки используется класс Expression.

Описание и определения класса находятся в заголовочный файле Expression.h и в файле исходного кода Expression.cpp.

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

// Открытие Form2

System::Windows::Forms::DialogResult dr;

Form2 ^newDlg = gcnew Form2();

m1: dr = newDlg->ShowDialog();

// Условия выбора пользователем, в какой textBox будет введено выражение

if (newDlg->radioButton1->Checked)

{

if (newDlg->textBox1->Text != "")

textBox11->Text = newDlg->textBox1->Text;

}

if (newDlg->radioButton2->Checked)

{

if (newDlg->textBox1->Text != "")

textBox22->Text = newDlg->textBox1->Text;

}

if (newDlg->radioButton3->Checked)

{

if (newDlg->textBox1->Text != "")

textBox33->Text = newDlg->textBox1->Text;

}

5.2 Руководство администратора

приложение математический программа

Программа «Генератор математических функций» предназначена для построения графиков функций по заданному выражению. Программа была разработана в интегрированной среде программирования Microsoft Visual Studio 2010. Приложение состоит из исполнимого модуля Zed.exe, файла главной формы Form1.cs и формы мастера функций Form2.cs. Описание и определения класса, используемого в программе для разбора выражения находится в файлах Expression (.h и .cpp файлы).

Изменение и усовершенствование программы можно проводить в Visual Studio 2010 (ранние версии не поддерживаются, в связи с изменением структуры хранения приложений). Для открытия исходного кода, надо открыть файл решения zed.sln. И далее выбрать нужный файл кода для просмотра.

Данная программа тестировалась на компьютере следующей конфигурации:

1. Процессор Intel(R) Core(TM) i5 CPU

2. ОЗУ 4.00 ГБ

3. ОС Microsoft Windows 7 Ultimate 32-разрядная

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

5.3 Руководство пользователя

Для запуска приложения нужно открыть файл zed.exe. После этого появится главная форма программы.

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

Построенные графики можно сохранить в файле в форматах: png, gif, jpg, tif, bmp.

Рекомендуемые требования к компьтеру:

- ЦП x86 или x64 с тактовой частотой 1ГГц

- Объем оперативной памяти 1 Гб

- Графический процессор с поддержкой DirectX 9 и 128 МБ памяти.

- Windows 7/Vista

- .NET FrameWork 4.0

Требования составлялись на основе требования ОС Windows 7, т.к. программа предназначена для работы в этой ОС.

Заключение

В данной работе были углублены знания, полученные в ходе лекционных и практических занятий. Получены навыки самостоятельной работы по формализации поставленной задачи, программированию, тестированию и отладке задач на ПЭВМ. Получены базовые навыки при разработке объектно-ориентированных программ. Разработана программа «Генератор математических функций».

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

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

1. Павловская Т.А. С/С++. Программирование на языке высокого уровня. - СПб.: Лидер, 2010. - 461с.

2. Библиотека MSDN msdn.microsoft.com.

3. Хортон А. Visual C++: базовый курс.: пер. с англ.- М.: ООО «И.Д. Вильямс», 2014 - 1152 с., ил.

Приложение А. Класс разбора математических функций

Expression.h

#ifndef EXPRESSION_H

#define EXPRESSION_H

#include <cmath>

#include <string>

#include <cstring>

#pragma once

class Expression

{

private:

struct sintElem {

char lexeme;

double number;

};

double * numArray;

sintElem* walkthroughArray;/*Массив в котором хранятся результаты предразбора строки.

Признаком конца такого массива является walkthroughArray[i].lexeme == 127*/

sintElem* start;/*Хранит ссылку на первый элемент массива walkthroughArray

чтобы восстановить её после исполнения вычислительной части*/

//Функции конструктора. Подробные коментарии указаны в теле функций.

/*Функции хранящиеся в файле ArifmometrSortSigment.

Комплекс функций необходим для сортировки в польскую нотацию*/

void sortPoland (sintElem* );

void recursionMain (sintElem*,short&,short&);

void recursionPlus (sintElem*,short&,short&);

void recursionMult (sintElem*,short&,short&);

void recursionPow (sintElem*,short&,short&);

void recursionUnary(sintElem*,short&,short&);

/*Функции хранящиеся в файле ArifmometrPreparationSigment.

Комплекс функция необходимых для полготовки строки к сортировке в польскую нотацию*/

void sintAdaptation (char* );

double setPoint (double, short );

static char* addMult (char* );

sintElem* setArray (char* );

static void addCode (char* );

static inline bool isNumber(char);

static inline bool isLetter(char);

static inline char* argTest(char*);

static inline bool isUnary(char);

sintElem doIt(char,sintElem);

sintElem doIt(char,sintElem,sintElem);

static bool isOperation(char);

unsigned operatorCount(sintElem*);

void delElements(sintElem*, unsigned);

public:

Expression();

Expression(const Expression&);

Expression(char*);

Expression(const std::string&);

Expression& rebild(const std::string&);

Expression& rebild(const char*);

~Expression(void);

static bool isExp(const std::string&);

static bool isExp(const char*);

//Функции выдающие результат вычисления

double calculate ();

double calculate (double);

double calculate (double,double);

Expression& optimization ();

};

#endif // EXPRESSION_H

Expression.cpp

#include "stdafx.h"

#include <cmath>

#include "Expression.h"

#include <iostream>

Expression::Expression()

: walkthroughArray(0)

, numArray(0)

{

rebild("0");

}

Expression::Expression(char* expression)

: walkthroughArray(0)

, numArray(0)

{

rebild(expression);

}

Expression::Expression(const std::string& expression)

: walkthroughArray(0)

, numArray(0)

{

rebild(expression.c_str());

}

Expression::Expression(const Expression& copy)

{

size_t sizeOfArr = 0;

while(copy.walkthroughArray[sizeOfArr].lexeme != 127)

++sizeOfArr;

walkthroughArray = new sintElem [sizeOfArr + 1];

for(size_t i = 0; i != sizeOfArr; ++i)

walkthroughArray[i] = copy.walkthroughArray[i];

walkthroughArray[sizeOfArr].lexeme = 127;

size_t i = 0,

numbersCount = 0;

while(walkthroughArray[i].lexeme != 127){

if(walkthroughArray[i].lexeme == 'x' || walkthroughArray[i].lexeme == 'y' || !walkthroughArray[i].lexeme)

++numbersCount;

++i;

}

numArray = new double[numbersCount + 1];

}

Expression::~Expression(void)

{

delete[] walkthroughArray;

delete[] numArray;

}

double Expression::calculate(){

return calculate(0,0);

}

double Expression::calculate(double x){

return calculate(x,0);

}

double Expression::calculate(double x, double y){

start = walkthroughArray;

while((*walkthroughArray).lexeme != 127) {

switch ((*walkthroughArray).lexeme) {

case 0:

*++numArray = (*walkthroughArray).number;

break;

case '+':/*Существует мнение что комутативные операции

могут выполнятся на разных платформах в разном

порядке поэтому дикримент перенесен в левую часть равенства*/

*(numArray-- - 1) += *numArray;

break;

case '*':

*(numArray-- - 1) *= *numArray;

break;

case '-':

*(numArray-- - 1) -= *numArray;

break;

case '%':

*numArray *= -1;

break;

case '/':

*(numArray-- - 1) /= *numArray;

break;

case '^':case -121:

*(numArray-- - 1) = pow(*(numArray-1),*numArray);

break;

case 'x':

*++numArray = x;

break;

case 'y':

*++numArray = y;

break;

case -128:

*numArray = sin(*numArray);

break;

case -127:

*numArray = cos(*numArray);

break;

case -126:

*numArray = tan(*numArray);

break;

case -125:

*numArray = 1 / tan(*numArray);

break;

case -124:

*(numArray-- - 1) = log(*(numArray-1))/log(*numArray);

break;

case -123:

*numArray = log10(*numArray);

break;

case -122:

*numArray = log(*numArray);

break;

case -120:

*numArray = pow(*numArray,0.5);

break;

case -119:

*numArray *= *numArray;

break;

case -118:

*numArray *= *numArray>0?1:-1;

break;

case -117:

*numArray = asin(*numArray);

break;

case -116:

*numArray = acos(*numArray);

break;

case -115:

*numArray = atan(*numArray);

break;

case -114:

*numArray = atan(1 / *numArray);

break;

case -113:

*numArray = sinh(*numArray);

break;

case -112:

*numArray = cosh(*numArray);

break;

}

//std::cout << *numArray << '\n';

++walkthroughArray;

}

--numArray;

walkthroughArray = start;

return numArray[1];

}

Expression& Expression::rebild(const std::string& st) { return rebild(st.c_str()); }

Expression& Expression::rebild(const char* expression)

{

delete[] walkthroughArray;

delete[] numArray;

//Переписываем содежимое строки expression в sourseString

int len = strlen(expression);

char* sourseString = new char[len *3];//Выражение, как правило, не длинное а нам пригодится память вовремя разбора. к тому же она будет очищена сразу после создания объекта

for (int i = 0, j = 0; i < len; ++i)

sourseString[j++] = expression[i];

sourseString[len] = 0;

sintAdaptation(sourseString);//Делает строку регистронезависимой, удаляет пробелы/'\t'/'\n', приводит скобочки к однообразию

addCode(sourseString);//Заменяет ссылки на функции символами от -128 для удобства дальнейшего анализа

addMult(sourseString);//Добавляет * и 0 для реализации унарного минуса. Функции объеденены по историческим причинам.

sortPoland(setArray(sourseString));/*При вызове преобразует строку в массив sintElem и высылает его для

сортировки в польскую нотацию*/

short i = 0,

numbersCount = 0,

opCount = 1;

while (walkthroughArray[i].lexeme != 127){

if (walkthroughArray[i].lexeme == 'x' || walkthroughArray[i].lexeme == 'y' || !walkthroughArray[i].lexeme)

++numbersCount;//Посчитать максимально возможное количество чисел в стеке(тоесть все числа вобще)

else

opCount += !isUnary(walkthroughArray[i].lexeme);

++i;

}

//qDebug() << opCount << '<' << numbersCount;

if (opCount > numbersCount)

{

//qDebug() << "fuck";

delete[] walkthroughArray;

delete[] numArray;

walkthroughArray = new sintElem[2];

walkthroughArray->number = walkthroughArray->lexeme = 0;

(walkthroughArray + 1)->lexeme = 127;

numArray = new double[1];

*numArray = 0.;

}

numArray = new double[numbersCount + 1];//1 лишний элемент нужен для оптимизации алгаритма вычисления

//std::cout << "объект создан.\n";

return *this;

}

short strlen(char* st){

/*Так как функция из библиотеки выдаёт ворнинг я её переписал*/

char* len = st;

while (*len) ++len;

return len - st;

}

void Expression::sintAdaptation (char* st){

int i = -1, j = 0;

while(st[++i])//Регистронезависимость и приведение скобочек к единообразию

if(st[i] >= 'A' && st[i] <= 'Z')

st[i] -= 'A' - 'a';

else if(st[i] == '{' || st[i] == '[')

st[i] = '(';

else if(st[i] == '}' || st[i] == ']')

st[i] = ')';

i = 0;

while(st[i - 1])//Убираю пробелы, символы табуляции и переноса строки

{

while(st[i] && ( st[i] == ' ' || st[i] == '\n' || st[i] == '\t'))

++i;

st[j] = st[i];

++j;

++i;

}

i = j = 0;

while(st[i - 1])//Убираю унарные плюсы

{

while(st[i] && st[i] == '+' && ( !i || st[i - 1] != ')' && !isNumber(st[i - 1]) ) )

++i;

st[j] = st[i];

++j;

++i;

}

}

void Expression::addCode (char* st)

{

int j,i=0;

while(st[i+3])

{

if(st[i]=='s'&&st[i+1]=='i'&&st[i+2]=='n')

{

st[i]=-128;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='c'&&st[i+1]=='o'&&st[i+2]=='s')

{

st[i]=-127;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='t'&&st[i+1]=='g')

{

st[i]=-126;

j=i+1;

while(st[j])

st[j]=st[j+++1];

}

else if(st[i]=='c'&&st[i+1]=='t'&&st[i+2]=='g')

{

st[i]=-125;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='l'&&st[i+1]=='o'&&st[i+2]=='g')

{

st[i]=-124;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='l'&&st[i+1]=='g')

{

st[i]=-123;

j=i+1;

while(st[j])

st[j]=st[j+++1];

}

else if(st[i]=='l'&&st[i+1]=='n')

{

st[i]=-122;

j=i+1;

while(st[j])

st[j]=st[j+++1];

}

else if(st[i]=='p'&&st[i+1]=='o'&&st[i+2]=='w')

{

st[i]=-121;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='s'&&st[i+1]=='q'&&st[i+2]=='r'&&st[i+3]=='t')

{

st[i]=-120;

j=i+1;

while(st[j+2])

st[j]=st[j+++3];

}

else if(st[i]=='s'&&st[i+1]=='q'&&st[i+2]=='r')

{

st[i]=-119;

j=i+1;

while(st[j+1])

st[j]=st[j+++2];

}

else if(st[i]=='a'&&st[i+1]=='b'&&st[i+2]=='s')

{

st[i]=-118;

j=i+1;

while(st[j+1])

st[j] = st[j+++2];

}

else if(st[i+4] && st[i+5])

if(st[i]=='a'&&st[i+1]=='r'&&st[i+2]=='c'&&st[i+3]=='s'&&st[i+4]=='i'&&st[i+5]=='n'){

st[i]=-117;

j=i+1;

while(st[j+4])

st[j] = st[j++ + 5];

}

else if(st[i]=='a'&&st[i+1]=='r'&&st[i+2]=='c'&&st[i+3]=='c'&&st[i+4]=='o'&&st[i+5]=='s'){

st[i]=-116;

j=i+1;

while(st[j+4])

st[j] = st[j++ + 5];

}

else if(st[i]=='a'&&st[i+1]=='r'&&st[i+2]=='c'&&st[i+3]=='t'&&st[i+4]=='g'){

st[i]=-115;

j=i+1;

while(st[j+3])

st[j] = st[j++ + 4];

}

else if(st[i]=='a'&&st[i+1]=='r'&&st[i+2]=='c'&&st[i+3]=='c'&&st[i+4]=='t'&&st[i+5]=='g'){

st[i]=-114;

j=i+1;

while(st[j+4])

st[j] = st[j++ + 5];

}

else if(st[i]=='s'&&st[i+1]=='i'&&st[i+2]=='n'&&st[i+3]=='h')

{

st[i]=-113;

j=i+1;

while(st[j+2])

st[j]=st[j+++3];

}

else if(st[i]=='c'&&st[i+1]=='o'&&st[i+2]=='s'&&st[i+3]=='h')

{

st[i]=-112;

j=i+1;

while(st[j+2])

st[j]=st[j+++3];

}

i++;

}

}

char* Expression::addMult (char* st)

/*Добавляет в анализируемую строку *. Ввиду сложности условвие срабатывания расписано в несколько строк

Функция не предназначена для полного решения вопроса а только помогает упростить ввод данных*/

{

int strLen = strlen(st),//Хрнаит длину строки изменяемую функцией!

i = 0, //Глобальный бегунок

j; //Бегунок используемый при добавлении '*'!

while (st[i]){

if (

(

((st[i]>47&&st[i]<58)||(st[i-1]=='p'&&st[i]=='i')||st[i]=='e'||st[i]=='x'||st[i]=='y'||st[i]==')')

&&

(st[i+1]=='(' || st[i+1]<=-100 || st[i+1]=='e' || st[i+1]=='p'&&st[i+2]=='i' || st[i+1] =='x' || st[i+1] == 'y')

)/*Если справа число или переменная или ) а слева (, x, pi, e или функция*/

||

(

((st[i-1]=='p'&&st[i]=='i')||st[i]=='e'||st[i]=='x'||st[i]=='y'||st[i]==')')

&&

( st[i+1]>='0' && st[i+1]<='9' )

)

)//Если нужно добавить *. Хоть и здоровенный но выносить в функцию не стал. Решил что не круто.

{

++strLen;

j=strLen;

st[j]=0;

while(i+1 != j)

{

--j;

st[j+1] = st[j];

}

st[j]='*';

}

++i;

}

//qDebug() << "theroes added $" << st << "$";

return st;

}

double Expression::setPoint (double arg, short del)

{

while(del--)

arg /= 10;

return arg;

}

Expression::sintElem* Expression::setArray (char* st)

/*

Преобразует строку в массив элементов следующего вида:

Каждый элемент имеет переменную lexeme типа char хранящую все лексэмы,

если же встречается число то оно записывается в переменную number типа double.

ВНИМАНИЕ! Признаком конца такого массива является выполнение равенства lexeme == 127

Воспринимает упоминания pi и e как чисел что делает невозможной экоспоненциальную форму записи числа в классическом виде.

если необходимо записать число в экспоненциальной форме пользуйтесь функцией pow,

анализатор оптимизирован для исполненя этой функции и упрощает алгоритм если

необходимо возвести в целую степень!

В анализаторе не предусмотрены методы позволяющие использовать не десятиричную форму представления чисел.

*/

{

int i=0;//Бегунок символьного массива

//Обозначаем унарную операцию заменив '-' на '%'

if(*st == '-')

*st = '%';

while(st[i++])

if(st[i-1] == '(' && st[i]=='-' && st[i+1]!='(' || (st[i-1] == '*' || st[i-1] == '/' || st[i-1] == '+' || st[i-1] == '-' || st[i-1] == '^') && st[i] == '-')

st[i] = '%';

int elKol=0;//Хранит количество элементов после завершения первого корневого цикла while

//Подсчитываем количество элементов чтобы выделить память. Выделяем память.

i=0;

while(st[i]){

//if(st[i] == '%' && st[i+1] == 'p' && st[i+2] == 'i')

//--elKol;//Если это вобще унарный минус перед пи

while((st[i] >= '0' && st[i] <= '9' || st[i] == '.' || st[i] == '%') && (st[i+1] >= '0' && st[i+1] <= '9' || st[i+1] == '.' || st[i+1] == 'p' || st[i+1] == 'e'))

++i;//Если текущий и следующий символы - части числа

if(st[i] == 'p' && st[i+1] == 'i')

++i;//Чтобы пи за 2 элемента не считать и включить унарный минус.

++elKol;

++i;

}

sintElem* firstAnalysisArray = new sintElem [elKol + 1];//Плюс место под признак конца масива

//Цикл основного анализа

i=0;

int point = 0, //Хранит количество знаков в числе после запятой.

j = 0, //Бегунок нового масива

det = 1; //Коэффициент учёта унарного минуса

bool isFigure = false;//Признак указывающий на то что до этого было число

while(st[i])

{

if(st[i]>='0'&&st[i]<='9')

if(point)//Если это число после запятой

firstAnalysisArray[j].number += setPoint(st[i] - '0',point++);

else if(isFigure){//Если не первая цифра числа

firstAnalysisArray[j].number *= 10;

firstAnalysisArray[j].number += st[i] - '0';

}

else{//Если это первая цифра в числе

firstAnalysisArray[j].lexeme = 0;//Фикссируем что это число

firstAnalysisArray[j].number = st[i] - '0';

isFigure = true;

if(i && st[i-1] == '%')//Если унарная операция

det=-1;

}

else if(st[i]=='.')

{

point=1;

if(!isFigure)

{

isFigure = true;

firstAnalysisArray[j].lexeme = 0;//Фикссируем что это число

firstAnalysisArray[j].number = 0.;

if(i && st[i-1] == '%')//Если унарная операция

det=-1;

}

}

else if(st[i]=='e'){

if(i && st[i - 1] == '%')

det = -1;

firstAnalysisArray[j].lexeme = 0;

firstAnalysisArray[j++].number = 2.718281828459045235360287471352662497757 * det;

det = 1;

}

else if(st[i]=='p'&&st[i+1]=='i'){

if(i && st[i - 1] == '%')

det=-1;

firstAnalysisArray[j].lexeme = 0;

firstAnalysisArray[j++].number = 3.141592653589793238462643383279502884197 * det;

det=1;//Занулить данные если раньше было число(рудиментарная форма защиты от ошибок)

++i;//отработано сразу два символа

}

else if(isFigure){

firstAnalysisArray[j++].number *= det;

firstAnalysisArray[j++].lexeme = st[i];

det = 1;

point = isFigure = 0;

}

else if(st[i] != '%' || st[i + 1] != 'p' && st[i + 1] != 'e' && ( st[i + 1] < '0' || st[i + 1] > '9' ) && st[i] != '.' )

firstAnalysisArray[j++].lexeme = st[i];

++i;

}

if(isFigure)

firstAnalysisArray[j].number *= det;

delete[] st;

firstAnalysisArray[elKol].lexeme = 127;//Записываем признак конца масcива

return firstAnalysisArray;

}

void Expression::recursionPlus (Expression::sintElem* sourseArray, short &i, short &j){

/*В случае +- мы ищем следующий +- или конец масива.

Рекурсия нужна чтобы всё остальное было полностью независимо*/

while(sourseArray[i].lexeme != '+' && sourseArray[i].lexeme != '-' && sourseArray[i].lexeme != 127){

if(!sourseArray[i].lexeme || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y')

walkthroughArray[j++] = sourseArray[i++];

else if(sourseArray[i].lexeme == '+' || sourseArray[i].lexeme == '-' || sourseArray[i].lexeme == '*' || sourseArray[i].lexeme == '/' || sourseArray[i].lexeme == '^' || sourseArray[i].lexeme < -100 || sourseArray[i].lexeme == '%'){

sintElem cnt = sourseArray[i];

switch(cnt.lexeme)

{

case'*':case'/':

recursionMult (sourseArray,++i,j);

break;

case'^':

recursionPow (sourseArray,++i,j);

break;

case'%':

recursionUnary(sourseArray,++i,j);

break;

default:

recursionMain (sourseArray,++(++i),j);

while(sourseArray[i].lexeme == ',')

recursionMain(sourseArray,++i,j);

++i;

}

walkthroughArray[j++] = cnt;

}

else if(sourseArray[i].lexeme == '('){

recursionMain(sourseArray,++i,j);

++i;

}

else if(sourseArray[i].lexeme == ')' || sourseArray[i].lexeme == ',')

return;

}

}

void Expression::recursionMult (Expression::sintElem* sourseArray, short &i, short &j){

//В случае /* мы ищем следующий /*-+ или конец масива

while(!sourseArray[i].lexeme || sourseArray[i].lexeme == '^' || sourseArray[i].lexeme == '%' || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y' || sourseArray[i].lexeme == '(' || sourseArray[i].lexeme < -100){

if(!sourseArray[i].lexeme || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y')

walkthroughArray[j++] = sourseArray[i++];

else if(sourseArray[i].lexeme == '^' || sourseArray[i].lexeme < -100 || sourseArray[i].lexeme == '%' ){

sintElem cnt = sourseArray[i];

switch(cnt.lexeme)

{

case '^'://свич уже вырожден в 2 исхода потому заменяется на if

recursionPow (sourseArray,++i,j);

break;

case '%':

recursionUnary(sourseArray,++i,j);

break;

default:

recursionMain (sourseArray,++(++i),j);

while(sourseArray[i].lexeme == ',')

recursionMain(sourseArray,++i,j);

++i;

}

walkthroughArray[j++] = cnt;

}

else if(sourseArray[i].lexeme == '('){

recursionMain(sourseArray,++i,j);

++i;

}

else if(sourseArray[i].lexeme == ')' || sourseArray[i].lexeme == ',')

return;

}

}

void Expression::recursionPow (Expression::sintElem* sourseArray, short &i, short &j){

//В случае ^ нам только и нужно что выписать содержимое идущих далее скобок или одно число

if(!sourseArray[i].lexeme || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y')

walkthroughArray[j++] = sourseArray[i++];

else if(sourseArray[i].lexeme < -100 || sourseArray[i].lexeme == '%'){//Это может быть только функция

sintElem cnt = sourseArray[i];

if(sourseArray[i].lexeme == '%'){

recursionUnary(sourseArray,++i,j);

}

else

{

recursionMain (sourseArray,++(++i),j);

while(sourseArray[i].lexeme == ',')

recursionMain(sourseArray,++i,j);

++i;//В конце стоит скобочка которую мы пропустили ++(++i) вызывая функцию

}

walkthroughArray[j++] = cnt;

}

else if(sourseArray[i].lexeme == '('){

recursionMain(sourseArray,++i,j);

++i;

}

}

void Expression::recursionUnary(Expression::sintElem* sourseArray, short &i, short &j){

//В случае % нам только и нужно что выписать содержимое идущих далее скобок или одно число

if(!sourseArray[i].lexeme || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y')

walkthroughArray[j++] = sourseArray[i++];

else if(sourseArray[i].lexeme < -100){//Это может быть только функция

sintElem cnt = sourseArray[i];

recursionMain(sourseArray,++(++i),j);

while(sourseArray[i].lexeme == ',')

recursionMain(sourseArray,++i,j);

++i;//В конце стоит скобочка которую мы пропустили ++(++i) вызывая функцию

walkthroughArray[j++] = cnt;

}

else if(sourseArray[i].lexeme == '('){

recursionMain(sourseArray,++i,j);

++i;

}

}

void Expression::recursionMain (Expression::sintElem* sourseArray,short&i,short&j){

while(sourseArray[i].lexeme != 127){

if(!sourseArray[i].lexeme || sourseArray[i].lexeme == 'x' || sourseArray[i].lexeme == 'y')

walkthroughArray[j++] = sourseArray[i++];

else if(sourseArray[i].lexeme == '+' || sourseArray[i].lexeme == '-' || sourseArray[i].lexeme == '*' || sourseArray[i].lexeme == '/' || sourseArray[i].lexeme == '^' || sourseArray[i].lexeme < -100 || sourseArray[i].lexeme == '%'){

sintElem cnt = sourseArray[i];

switch(cnt.lexeme)

{//Для +-/*^ приходится писать рекурсивную функцию другого вида с другими условиями выхода

case'+':case'-':

recursionPlus(sourseArray,++i,j);

break;

case'*':case'/':

recursionMult(sourseArray,++i,j);

break;

case'^':

recursionPow (sourseArray,++i,j);

break;

case'%':

recursionUnary (sourseArray,++i,j);

break;

default://Если это не операции +-/*^ значит это функция и за её кодом идут скобки -> ++(++i)

recursionMain(sourseArray,++(++i),j);

while(sourseArray[i].lexeme == ',')

recursionMain(sourseArray,++i,j);

++i;//В конце стоит скобочка которую мы пропустили ++(++i) вызывая функцию

}

walkthroughArray[j++] = cnt;

}

else if(sourseArray[i].lexeme == '('){

recursionMain(sourseArray,++i,j);

++i;

}

else if(sourseArray[i].lexeme == ')' || sourseArray[i].lexeme == ',')

return;

}

}

void Expression::sortPoland (sintElem* sourseArray)

{

short int elemQuantity = 0,//Колличество элементов в новом масиве

i = 0, //Бегунок старого масива

j = 0; //Бегунок нового масива

while(sourseArray[i].lexeme != 127)

if(sourseArray[i++].lexeme != '(' && sourseArray[i-1].lexeme != ')' && sourseArray[i-1].lexeme != ',')

++elemQuantity;

walkthroughArray = new sintElem [elemQuantity + 1];


Подобные документы

  • Техническое задание и блок-схема алгоритма программы построения графиков функций. Инструкция по инсталляции и описание работы программного продукта GRAPHIC. Инструкция оператору и ограничения данной версии программы. Программный код приложения.

    курсовая работа [391,2 K], добавлен 05.12.2009

  • Разработка программы с использованием принципов объектно-ориентированного программирования на языке высокого уровня С средствами Microsoft Visual Studio 2010. Построение алгоритма реализации. Класс программы, инструкция по использованию программы.

    курсовая работа [1,0 M], добавлен 26.12.2013

  • Особенности использования встроенных функций Microsoft Excel. Создание таблиц, их заполнение данными, построение графиков. Применение математических формул для выполнения запросов с помощью пакетов прикладных программ. Технические требования к компьютеру.

    курсовая работа [1,1 M], добавлен 25.04.2013

  • Введение в объектно-ориентированное программирование. Постановка задачи. Описание алгоритма решения в псевдокоде (команды в виде текста на русском языке). Исходный текст программы на С. Тестирование программы. Модификация программы. Полиморфизм.

    курсовая работа [294,0 K], добавлен 08.09.2008

  • Создание программы для обработки информации об объектах предметной области "Бытовая техника" в среде визуального программирования C++. Иерархия родственных классов. Описание логической структуры программы. Реализация файлового ввода/вывода данных.

    курсовая работа [711,4 K], добавлен 27.07.2014

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

    курсовая работа [2,2 M], добавлен 14.04.2019

  • Создание круговой диаграммы в табличном процессоре Microsoft Office Excel. Построение графиков математических функций. Назначение и алгоритм построение диаграммы с помощью Мастера диаграмм. Типы диаграмм в Excel. Метки строк и столбцов диаграммы.

    лабораторная работа [1,6 M], добавлен 15.11.2010

  • Составление отчетной ведомости "Магазины" в Excel 2013. Работа с таблицами семейства Microsoft Office. Построение круговой диаграммы и гистограммы, графиков. Разработка процедур для табулирования функций. Программирование функций пользователя на VBA.

    курсовая работа [2,6 M], добавлен 03.04.2014

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

    контрольная работа [614,7 K], добавлен 16.09.2012

  • Разработка учебного приложения, играющего роль клавиатурного тренажёра. Установка различных опций. Использование средств Borland C++Builder 6.0. Объектно-ориентированное проектирование и программирование системы. Тестирование и отладка программы.

    курсовая работа [730,4 K], добавлен 23.07.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.