koala написав:Ось цей фрагмент
If (PExpression[i] = '*') Or (PExpression[i] = '/') Then
Begin
If PExpression[i] = '*' Then
Begin
LOperator := '*';
LOperatorPosition := I;
Break
End
Else
Begin
LOperator := '/';
LOperatorPosition := I;
Break
End;
End;
End;
можна скоротити. Оскільки PExpression[i] або '*', або '/', то можна зробити
LOperator := PExpression[i];
і тоді повністю прибрати внутрішній if:
If (PExpression[i] = '*') Or (PExpression[i] = '/') Then
Begin
LOperator := PExpression[i];
LOperatorPosition := I;
Break
End;
Ну і не зрозуміло, нащо перетворювати число на стрічку перед поверненням.
Цей фрагмент навряд чи можна скоротити тому що в виразі який отримує функція в якості рядка може бути вираз: 2563,25*563,06+25,23*37,54/2 і тоді позиція оператора множення береться буде не 8 а 21, а якщо там буде два тири оператора множення. І тоді не буде послідовного виконання операторів.
Мені потрібно послідовно іти з ліва на право виконувати дії.
Першочерговість множення або ділення потім додавання або віднімання.
Тобто функція знайшла оператора перевірила чи це множення чи це ділення (якщо так) виконала витяг числа з права від оператора та з ліва від оператора(мітка закінчення витягу першого операнда або початок рядка або інший оператор, другого операнда або оператор або кінець рядка). Передала числа та оператора в іншу функцію на обрахування. Інша функція повернула результат і цим результатом замінила числа та оператора в рядку які витягувались. І далі знову з ліва на право ітерація чи рекурсія (поки не визначився, тільки почав писати). Якщо множення і ділення немає до кінця рядка то тоді те саме з ліва на право з додаванням і відніманням.
Тобто мені від початку і до кінця рядка потрібно перевірити всі множення і ділення, коли їх не залишиться потрібно перевірити всі додавання і віднімання.
Ось чернетка функції без всяких видалень (тільки начав писати)
Function ExpressionAnswer(PExpression: String): String;
Var
LBack, LAhead, I: Integer; // Лічильник циклу
// Operand1, Operand2: String;
LOperatorPosition: Integer;
LOperator: Char; // Оператор
LDeleteStartPosition, LDeleteEndPosition: Integer; // Позиції видалення виразу
LFirstOperand, LSecondOperand: Extended; // Перший та другий операнди
Begin
I := 1;
Result := '';
// Від початку і до кінця виразу
For I := 1 To Length(PExpression) Do
Begin
//Result := '';
LDeleteStartPosition := 0;
LDeleteEndPosition := 0;
// Operand1 := '';
// Operand2 := '';
{Виконуємо з ліва на право множення або ділення}
If (PExpression[i] = '*') Or (PExpression[i] = '/') Then
Begin
If PExpression[i] = '*' Then
Begin
LOperator := '*';
LOperatorPosition := I;
Result := IntToStr(LOperatorPosition);
Break
End
Else
Begin
LOperator := '/';
LOperatorPosition := I;
Result := IntToStr(LOperatorPosition);
Break
End;
End;
// {Витягуэмо число перед оператором}
//
// For LBack := (LOperatorPosition - 1) DownTo 1 Do
// If (PExpression[LBack]= '/') Or (PExpression[LBack]= '+') Or
// (PExpression[LBack]= '-') Then
// Break
// Else
// LDeleteStartPosition := LBack;
//
// If PExpression[LBack] <> ' ' Then
// LFirstOperand := StrToFloat(Copy(PExpression,LBack,(I - 1) - LBack));
//
// {Витягуэмо число після оператороа}
//
// For LAhead := I To Length(PExpression) Do
// If (PExpression[LBack]= '/') Or (PExpression[LBack]= '+') Or (PExpression[LBack]= '-') Then
// Break;
End;
Result := FloatToStr(LOperatorPosition);
End;
Т справа поки не в оптимізації коду, мене цікавить чому Result := FloatToStr(LOperatorPosition);в коді вище нічого не виводить мені???
А в слідуючому коді Result := FloatToStr(LOperatorPosition); виводить позицію оператора. Де я помилився? Після Break в LOperatorPosition чи в LOperator має ж щось зберігатися? Пробую в Мемо, що позицію вивести, що LOperator: Char; порожньо!!! Чому???
//Відповідь обрахунку виразу
Function ExpressionAnswer(PExpression: String): String;
Var
LBack, LAhead, I: Integer; // Лічильник циклу
// Operand1, Operand2: String;
LOperatorPosition: Integer;
LOperator: Char; // Оператор
LDeleteStartPosition, LDeleteEndPosition: Integer; // Позиції видалення виразу
LFirstOperand, LSecondOperand: Extended; // Перший та другий операнди
Begin
I := 1;
Result := '';
// Від початку і до кінця виразу
For I := 1 To Length(PExpression) Do
Begin
//Result := '';
LDeleteStartPosition := 0;
LDeleteEndPosition := 0;
// Operand1 := '';
// Operand2 := '';
{Виконуємо з ліва на право множення або ділення}
If (PExpression[i] = '*') Or (PExpression[i] = '/') Then
Begin
If PExpression[i] = '*' Then
Begin
LOperator := '*';
LOperatorPosition := I;
Result := FloatToStr(LOperatorPosition);
Result := IntToStr(LOperatorPosition);
Break
End
Else
Begin
LOperator := '/';
LOperatorPosition := I;
Result := FloatToStr(LOperatorPosition);
Result := IntToStr(LOperatorPosition);
Break
End;
End;
// {Витягуэмо число перед оператором}
//
// For LBack := (LOperatorPosition - 1) DownTo 1 Do
// If (PExpression[LBack]= '/') Or (PExpression[LBack]= '+') Or
// (PExpression[LBack]= '-') Then
// Break
// Else
// LDeleteStartPosition := LBack;
//
// If PExpression[LBack] <> ' ' Then
// LFirstOperand := StrToFloat(Copy(PExpression,LBack,(I - 1) - LBack));
//
// {Витягуэмо число після оператороа}
//
// For LAhead := I To Length(PExpression) Do
// If (PExpression[LBack]= '/') Or (PExpression[LBack]= '+') Or (PExpression[LBack]= '-') Then
// Break;
End;
End;