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




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];

i = 0;

recursionMain(sourseArray, i, j);//i и j педедаются по ссылке(!)

walkthroughArray[j].lexeme = 127;

}

 

bool Expression::isExp(const std::string& str)

{

return isExp(str.c_str());

}

bool Expression::isNumber(char s) { return s >= '0' && s <= '9' || s == 'x' || s == 'y'; }

bool Expression::isLetter(char s) { return s >= 'a' && s <= 'z'; }

bool Expression::isExp(const char* St)

{

int i = -1, j = 0;

char* st = new char [strlen(St) * 2];

while(St[++i])//Проверка на наличие посторонних символов

if(St[i]!= ' ' && St[i]!= '\n')

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

st[j++] = St[i] - ('A' - 'a');

else if(isLetter(St[i]) || isNumber(St[i]) ||

St[i] == '*' || St[i] == '/' || St[i] == '+' || St[i] == '-' ||

St[i] == '^' || St[i] == '(' || St[i] == ')' || St[i] == ',' || St[i] == '.')

st[j++] = St[i];

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

st[j++] = ')';

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

st[j++] = '(';

else

{

delete[] st;

return!true &&!false;

}

i = -1;

while(st[++i])

if(st[i] == 'p' && st[i + 1] == 'i')//Если это pi, заменить его на 77, чтобы в дальнейшем анализировать как число

{

st[i] = '7';

st[++i] = '7';

}

else if(st[i] == 'e' || st[i] == 'x' || st[i] =='y')//если это e, y или x

st[i] = '2';

st[j] = i = 0;

//std::cout << "Symbols is right.\nFree string is \"" << st << "\"\n";

if(*st!= 0 && (*st!= '+' && *st!= '-' && *st!= '(' &&!isNumber(*st) &&!isLetter(*st)))//Проверка на порядок следования

{

delete[] st;

return!true &&!false;

}

 

while(st[++i])

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

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

|| st[i] == ')' &&

!isNumber(st[i + 1]) &&!isLetter(st[i + 1]) && st[i + 1]!= '(' && st[i + 1]!= '-' && st[i + 1]!= '+' && st[i + 1]!= '^'

&& st[i + 1]!= ')' && st[i + 1]!= '*' && st[i + 1]!= '/' && st[i + 1]!= ',' && st[i + 1]

|| isLetter(st[i]) &&

(!st[i + 1] ||!isLetter(st[i + 1]) && st[i + 1]!= '('))

{

 

delete[] st;

return!true &&!false;

}

//Тест последнего символа

--i;

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

{

delete[] st;

return!true &&!false;

}

//std::cout << "Sequence is right.\n";

//qDebug() << "()...";

i = -1;

j = 0;

while(st[++i])//Проверка на скобочки

{

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

++j;

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

--j;

if(j < 0)

{

delete[] st;

return!true &&!false;

}

}

if(j)

{

delete[] st;

return!true &&!false;

}

//std::cout << "Brackets is right.\n";

//qDebug() << "funk...";

addCode(st);

i = -1;

while(st[++i])

{

if(isLetter(st[i]))//Если есть неопознанные функции - символы не заменённые на экваваленты

{

//std::cout << st << std::endl;

delete[] st;

return!true &&!false;

}

}

delete[] st;

return true;

}

 

char* Expression::argTest(char* st)

{

int j =!isUnary(*st);

++(++st);

int lBr = 1, rBr = 0;

while (*st && lBr!= rBr)

{

j -= *st == ',';

lBr += *st == '(';

rBr += *st == ')';

if (*st < -100)

{

st = argTest(st);

if (!st)

{

return 0;

}

}

++st;

}

if (lBr!= rBr || j)

{

return 0;

}

return ++st;

}

bool Expression::isUnary(char s) { return s == '%' || s < -100 && s!= -124 && s!= -121; }

bool Expression::isOperation(char s) { return s && s!= 'x' && s!= 'y'; }

Expression::sintElem Expression::doIt(char op, sintElem a)

{

//std::cout << op << a.number << std::endl;

sintElem ret;

ret.lexeme = 0;

switch (op)

{

case '%':

ret.number = 0 - a.number;

break;

case -128:

ret.number = sin(a.number);

break;

case -127:

ret.number = cos(a.number);

break;

case -126:

ret.number = tan(a.number);

break;

case -125:

ret.number = 1 / tan(a.number);

break;

case -123:

ret.number = log10(a.number);

break;

case -122:

ret.number = log(a.number);

break;

case -120:

ret.number = pow(a.number,0.5);

break;

case -119:

ret.number = a.number * a.number;

break;

case -118:

ret.number = *numArray>0? a.number: 0 - a.number;

break;

case -117:

ret.number = asin(a.number);

break;

case -116:

ret.number = acos(a.number);

break;

case -115:

ret.number = atan(a.number);

break;

case -114:

ret.number = atan(1 / a.number);

break;

case -113:

ret.number = sinh(a.number);

break;

case -112:

ret.number = cosh(a.number);

break;

}

return ret;

}

Expression::sintElem Expression::doIt(char op, sintElem a, sintElem b)

{

//std::cout << a.number << op << b.number << std::endl;

sintElem ret;

ret.lexeme = 0;

switch (op)

{

case '+':

ret.number = a.number + b.number;

break;

case '*':

ret.number = a.number * b.number;

break;

case '-':

ret.number = a.number - b.number;

break;

case '/':

ret.number = a.number / b.number;

break;

case '^':case -121:

ret.number = pow(a.number, b.number);

break;

case -124:

ret.number = log(a.number)/log(b.number);

break;

}

return ret;

}

unsigned Expression::operatorCount(sintElem* op)

{

unsigned k = 1;

signed j = 0;

while(k)//проверку на достижение начала массива ставить не нужно, если мы предпологаем нотацию разрешаемой

k += isOperation(op[-++j].lexeme)?!isUnary(op[-j].lexeme): -1;//по моему это приведёс нас ко второму операнду

return j;

}

void Expression::delElements(sintElem* from, unsigned how)

{

for(unsigned i = 0; from[i + how - 1].lexeme!= 127; ++i)

from[i] = from[i + how];

}

Expression& Expression::optimization()

{

unsigned counter = 0;

while(walkthroughArray[counter].lexeme!= 127)

++counter;

sintElem* temp = new sintElem[counter + 1];

 

unsigned i = 0, j = 0;

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

{

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

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

else

if(isUnary(walkthroughArray[i].lexeme))

if(!temp[j - 1].lexeme)

temp[j - 1] = doIt(walkthroughArray[i].lexeme, temp[j - 1]);

else

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

else

if(!temp[j - 1].lexeme &&!temp[j - 2].lexeme)

temp[j - 1] = doIt(walkthroughArray[i].lexeme, temp[j - 1], temp[--j]);

else

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

++i;

}

temp[j].lexeme = 127;

 

i = j = 0;

if(temp[1].lexeme!= 127)

++(++i);//речь о бинарных операциях, нет смысла изучать что там раньше третьего знака.

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

{

switch(temp[i].lexeme)

{

case '*':

if(!temp[i - 1].lexeme && temp[i - 1].number == 1)//правый операнд мы можем проверить сразу

{

delElements(temp + i - 1, 2);//убираем 1 и *

--(--i);

}

else if(!temp[i - 1].lexeme && temp[i - 1].number == 0)

{

temp[i].lexeme = 0;

temp[i].number = 0;//Чтобы не вызывать два удаления записываем 0 вместо *

j = operatorCount(temp + i - 1);//собираем второй операнд, удаляем его и *.

delElements(temp + i - j - 1, j + 1);

i -= j + 1;

}

else//иначе просто собираем всё что попадает в правый операнд

{

j = operatorCount(temp + i);

if(!temp[i - j - 1].lexeme && temp[i - j - 1].number == 1)

{//удаляем 1 и само умножение.

delElements(temp + i, 1);

delElements(temp + i - j - 1, 1);

--(--i);

}

else if(!temp[i - j - 1].lexeme && temp[i - j - 1].number == 0)

{

delElements(temp + i - j, j + 1);//удаляем всё кроме нуля

i -= j + 1;

}

}

break;

case '+': case '-':

if(!temp[i - 1].lexeme && temp[i - 1].number == 0)

{

delElements(temp + i - 1, 2);

--(--i);

}

else

{

j = operatorCount(temp + i);

if(!temp[i - j - 1].lexeme && temp[i - j - 1].number == 0)

{

delElements(temp + i, 1);

delElements(temp + i - j - 1, 1);

--(--i);

}

}

break;

case '/':

if(!temp[i - 1].lexeme && temp[i - 1].number == 1)

{

delElements(temp + i - 1, 2);

--(--i);

}

if(!temp[i - 1].lexeme && temp[i - 1].number == 0)

{

temp[i].lexeme = 0;

temp[i].number = 1;

j = operatorCount(temp + i - 1);

delElements(temp + i - j - 1, j + 1);

i -= j + 1;

}

else

{

j = operatorCount(temp + i);

if(!temp[i - j - 1].lexeme && temp[i - j - 1].number == 0)

{

delElements(temp + i - j, j + 1);

i -= j + 1;

}

}

break;

case '^': case -121:

if(!temp[i - 1].lexeme && temp[i - 1].number == 1)

{

delElements(temp + i - 1, 2);

--(--i);

}

else

{

j = operatorCount(temp + i);

if(!temp[i - j - 1].lexeme && (temp[i - j - 1].number == 0 || temp[i - j - 1].number == 1))

{

delElements(temp + i - j, j + 1);

i -= j + 1;

}

}

break;

}

++i;

}

 

delete[] walkthroughArray;

walkthroughArray = temp;

 

/*

std::cout << "Оптимизированная нотация:\n";

for(i = 0; walkthroughArray[i].lexeme!= 127; ++i)

if(walkthroughArray[i].lexeme)

std::cout << walkthroughArray[i].lexeme << std::endl;

else

std::cout << walkthroughArray[i].number << std::endl;

//*/

 

return *this;

}


Приложение Б. Листинг

Листинг Б.1 - Файл zed.cpp, запускающий программу

Form1.h

#pragma once

#include <math.h>

#include "Form2.h"

#include "stdafx.h"

 

namespace zed {

 

using namespace System;

using namespace System::ComponentModel;

using namespace System::Collections;

using namespace System::Windows::Forms;

using namespace System::Data;

using namespace System::Drawing;

using namespace ZedGraph;

 

 

public ref class Form1: public System::Windows::Forms::Form

{

 

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

public:

char* SystemStringToChar(System::String^ string)

{

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

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

}

 

// Функция преобразования компонента 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();

}

 

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

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);

}

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

if(textBox22->Text!= "")

{

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

char *stroka2 = SystemStringToChar(textBox22->Text);

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

LineItem ^F2Curve=(LineItem ^)zedGraphControl1->GraphPane->CurveList[1];

IPointListEdit ^list2= (IPointListEdit ^) F2Curve->Points;

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

{

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

Expression exp(stroka2);

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

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

}

else

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

}

 

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

if(textBox33->Text!= "")

{

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

char *stroka3 = SystemStringToChar(textBox33->Text);

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

LineItem ^F3Curve=(LineItem ^)zedGraphControl1->GraphPane->CurveList[2];

IPointListEdit ^list3= (IPointListEdit ^) F3Curve->Points;

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

{

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

Expression exp(stroka3);

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

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

}

else

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

}

 

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

zedGraphControl1->AxisChange ();

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

zedGraphControl1->Invalidate();

}

// Объявляем глобальные переменные, чтобы они запоминали значения в textBox_x1 и textBox_x2

double temp_x1, temp_x2;

 

public:

Form1(void)

{

InitializeComponent();

}

 

protected:

~Form1()

{

if (components)

{

delete components;

}

}

private: ZedGraph::ZedGraphControl^ zedGraphControl1;

private: System::Windows::Forms::Button^ button1;

private: System::Windows::Forms::Button^ button_master;

private: System::Windows::Forms::Button^ button_End;

private: System::Windows::Forms::TextBox^ textBox11;

private: System::Windows::Forms::Label^ label1;

private: System::Windows::Forms::Button^ button2;

private: System::Windows::Forms::Button^ button_save;

private: System::Windows::Forms::TextBox^ textBox_x2;

private: System::Windows::Forms::Label^ label3;

private: System::Windows::Forms::TextBox^ textBox_x1;

private: System::Windows::Forms::Label^ label2;

private: System::Windows::Forms::CheckBox^ checkBox1;

private: System::Windows::Forms::Label^ label4;

private: System::Windows::Forms::TextBox^ textBox22;

private: System::Windows::Forms::Label^ label5;

private: System::Windows::Forms::TextBox^ textBox33;

private: System::Windows::Forms::ToolTip^ toolTip1;

private: System::ComponentModel::IContainer^ components;

 

#pragma region Windows Form Designer generated code

 

void InitializeComponent(void)

{

this->components = (gcnew System::ComponentModel::Container());

this->button1 = (gcnew System::Windows::Forms::Button());

this->zedGraphControl1 = (gcnew ZedGraph::ZedGraphControl());

this->button_master = (gcnew System::Windows::Forms::Button());

this->button_End = (gcnew System::Windows::Forms::Button());

this->textBox11 = (gcnew System::Windows::Forms::TextBox());

this->label1 = (gcnew System::Windows::Forms::Label());

this->button2 = (gcnew System::Windows::Forms::Button());

this->button_save = (gcnew System::Windows::Forms::Button());

this->textBox_x2 = (gcnew System::Windows::Forms::TextBox());

this->label3 = (gcnew System::Windows::Forms::Label());

this->textBox_x1 = (gcnew System::Windows::Forms::TextBox());

this->label2 = (gcnew System::Windows::Forms::Label());

this->checkBox1 = (gcnew System::Windows::Forms::CheckBox());

this->label4 = (gcnew System::Windows::Forms::Label());

this->textBox22 = (gcnew System::Windows::Forms::TextBox());

this->label5 = (gcnew System::Windows::Forms::Label());

this->textBox33 = (gcnew System::Windows::Forms::TextBox());

this->toolTip1 = (gcnew System::Windows::Forms::ToolTip(this->components));

this->SuspendLayout();

//

// button1

//

this->button1->Location = System::Drawing::Point(12, 129);

this->button1->Name = L"button1";

this->button1->Size = System::Drawing::Size(118, 53);

this->button1->TabIndex = 0;

this->button1->Text = L"Построить график";

this->toolTip1->SetToolTip(this->button1, L"Построение графиков");

this->button1->UseVisualStyleBackColor = true;

this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);

//

// zedGraphControl1

//

this->zedGraphControl1->Location = System::Drawing::Point(162, 128);

this->zedGraphControl1->Name = L"zedGraphControl1";

this->zedGraphControl1->ScrollGrace = 0;

this->zedGraphControl1->ScrollMaxX = 0;

this->zedGraphControl1->ScrollMaxY = 0;

this->zedGraphControl1->ScrollMaxY2 = 0;

this->zedGraphControl1->ScrollMinX = 0;

this->zedGraphControl1->ScrollMinY = 0;

this->zedGraphControl1->ScrollMinY2 = 0;

this->zedGraphControl1->Size = System::Drawing::Size(698, 503);

this->zedGraphControl1->TabIndex = 1;

//

// button_master

//

this->button_master->Location = System::Drawing::Point(770, 13);

this->button_master->Name = L"button_master";

this->button_master->Size = System::Drawing::Size(90, 91);

this->button_master->TabIndex = 2;

this->button_master->Text = L"Мастер функций";

this->toolTip1->SetToolTip(this->button_master, L"Мастер функций");

this->button_master->UseVisualStyleBackColor = true;

this->button_master->Click += gcnew System::EventHandler(this, &Form1::button_master_Click);

//

// button_End

//

this->button_End->Location = System::Drawing::Point(12, 467);

this->button_End->Name = L"button_End";

this->button_End->Size = System::Drawing::Size(118, 53);

this->button_End->TabIndex = 3;

this->button_End->Text = L"Выход";

this->toolTip1->SetToolTip(this->button_End, L"Выход");

this->button_End->UseVisualStyleBackColor = true;

this->button_End->Click += gcnew System::EventHandler(this, &Form1::button_End_Click);

//

// textBox11

//

this->textBox11->Location = System::Drawing::Point(208, 12);

this->textBox11->Name = L"textBox11";

this->textBox11->Size = System::Drawing::Size(556, 20);

this->textBox11->TabIndex = 4;

this->toolTip1->SetToolTip(this->textBox11, L"выражение f(x)");

//

// label1

//

this->label1->AutoSize = true;

this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,

static_cast<System::Byte>(204)));

this->label1->Location = System::Drawing::Point(162, 12);

this->label1->Name = L"label1";

this->label1->Size = System::Drawing::Size(40, 20);

this->label1->TabIndex = 5;

this->label1->Text = L"f(x)=";

//

// button2

//

this->button2->Location = System::Drawing::Point(12, 236);

this->button2->Name = L"button2";

this->button2->Size = System::Drawing::Size(118, 53);

this->button2->TabIndex = 6;

this->button2->Text = L"Очистить";

this->toolTip1->SetToolTip(this->button2, L"Очистить область построения графиков");

this->button2->UseVisualStyleBackColor = true;

this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);

//

// button_save

//

this->button_save->Location = System::Drawing::Point(12, 349);

this->button_save->Name = L"button_save";

this->button_save->Size = System::Drawing::Size(118, 53);

this->button_save->TabIndex = 7;

this->button_save->Text = L"Сохранить график";

this->toolTip1->SetToolTip(this->button_save, L"Сохранение графиков в файл");

this->button_save->UseVisualStyleBackColor = true;

this->button_save->Click += gcnew System::EventHandler(this, &Form1::button_save_Click);

//

// textBox_x2

//

this->textBox_x2->Location = System::Drawing::Point(113, 578);

this->textBox_x2->Name = L"textBox_x2";

this->textBox_x2->Size = System::Drawing::Size(25, 20);

this->textBox_x2->TabIndex = 15;

this->textBox_x2->Text = L"10";

this->toolTip1->SetToolTip(this->textBox_x2, L"Диапазон значений X");

this->textBox_x2->TextChanged += gcnew System::EventHandler(this, &Form1::textBox_x2_TextChanged);

//

// label3

//

this->label3->AutoSize = true;

this->label3->Location = System::Drawing::Point(88, 581);

this->label3->Name = L"label3";

this->label3->Size = System::Drawing::Size(19, 13);

this->label3->TabIndex = 14;

this->label3->Text = L"до";

//

// textBox_x1

//

this->textBox_x1->Location =



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-12-08 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: