Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.05.06;
Скачать: CL | DM;

Вниз

Как заставить Делфи выполнить мат. выражение ?   Найти похожие ветки 

 
Termik   (2002-04-23 09:58) [0]

Дано: a:="5+3*8..." и т.д. Как заставить Делфи выполнить выражение, записанное в переменную ? В выражении также могут присутствовать скобки и функциии.
Заранее благодарен.


 
Alx2   (2002-04-23 10:05) [1]

Сначала обрабатываем скобки, функции, потом высокоприоритетные операции ("*","/"), потом остальные.
короче говоря, пишется стандартный parser со стандартной разбивкой на лексемы.


 
VictorT   (2002-04-23 10:06) [2]

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


 
kronprince   (2002-04-23 10:08) [3]

Никак.:(

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

Sorry, но у меня исходников не сохранилось.:(


 
Termik   (2002-04-23 10:11) [4]

2VictorT Мыло видишь ?
Заливай !


 
IPisk   (2002-04-23 10:40) [5]

В библиотеке RX есть готовый парсер

function GetFormulaValue(const Formula: string): Extended;


 
VictorT   (2002-04-23 10:40) [6]


> Termik © (23.04.02 10:11)

Залил.


 
VictorT   (2002-04-23 10:44) [7]


> IPisk © (23.04.02 10:40)

Когда-то смотрел этот парсер, нашёл там кое-какие глюки (вроде связанные с пробелами), хотя не помню какая версия RX, может уже и исправили.


 
IPisk   (2002-04-23 10:47) [8]

> VictorT ©
Ошибок с RX не наблюдалось (версия 2.75)


 
Termik   (2002-04-23 11:06) [9]

Большое спасибо всем вам за то, что приняли участие в моей проблеме ! :))


 
VictorT   (2002-04-23 11:21) [10]


> IPisk © (23.04.02 10:47)

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


 
Alx2   (2002-04-23 11:51) [11]

Вот, "на скору руку" накидал. Мусора в строке быть не должно. Переменная k покажет место, где тормознули в случае ошибки.

Function EvalExpr(S: String): Double;
Type
TFuncNames = (fnone, fsin, fcos, ftan, farctan, fsqr, fsqrt);
Var K: Integer;
Function Expr: Double; Forward;

Function ReadFuncName: TFuncNames;
Var tmpStr: String;
Start: Integer;
Begin
Result := fnone;
Start := K;
While S[K] In ["a".."z", "A".."Z", "0".."9"] Do inc(K);
tmpStr := UpperCase(Copy(S, Start, K - Start));
If tmpStr = "SIN" Then Result := fsin Else
If tmpStr = "COS" Then Result := fcos Else
If tmpStr = "TAN" Then Result := ftan Else
If tmpStr = "ARCTAN" Then Result := farctan Else
If tmpStr = "SQR" Then Result := fsqr Else
If tmpStr = "SQRT" Then Result := fsqrt;
End;

Function ATOM: Double;
Var
tmp : Double;
tmpStr: String;
Code : Integer;
Begin
Result := 0;
If S[K] = "(" Then
Begin
inc(K);
Result := Expr;
inc(K);
End
Else
Begin
tmpStr := Copy(S, K, Length(S));
Val(tmpStr, tmp, Code);
If Code > 1 Then
Begin
K := K + Code - 1;
SetLength(tmpStr, Code - 1);
Val(tmpStr, tmp, Code);
If Code <> 0 Then exit;
Result := tmp;
End
Else
Begin
Case ReadFuncName Of
fsin: Result := sin(ATOM);
fcos: Result := cos(ATOM);
ftan: Result := tan(ATOM);
farctan: Result := arctan(ATOM);
fsqr: Result := sqr(ATOM);
fsqrt: Result := sqrt(ATOM);
End;
End;
End;
End;

Function Term: Double;
Var Ch: Char;
Begin
Result := ATOM;
Ch := S[K];
While Ch In ["*", "/"] Do
Begin
inc(K);
Case Ch Of
"*": Result := Result * ATOM;
"/": Result := Result / ATOM;
End;
Ch := S[K];
End;
End;

Function Expr: Double;
Var Ch: Char;
Begin
Result := Term;
Ch := S[K];
While Ch In ["+", "-"] Do
Begin
inc(K);
Case Ch Of
"+": Result := Result + Term;
"-": Result := Result - Term;
End;
Ch := S[K];
End;
End;

Begin
K := 1;
S := S + " ";
Result := Expr;
End;
// Пример использования:
Var S: String;
Begin
S := Edit2.Text;
Edit3.Text := FloatToStr(EvalExpr(S));
End;


Будут вопросы - задавай по мылу.


 
Alx2   (2002-04-23 12:05) [12]

Да еще: надо подключить модуль math, чтобы tan считался.


 
VictorT   (2002-04-23 12:05) [13]


> Alx2 © (23.04.02 11:51)

Уважаю, если на скорую руку... Я вначале пару дней книжки читал, пока первую строчку не написал.


 
Alx2   (2002-04-23 12:08) [14]

>VictorT © (23.04.02 12:05)
Формальные языки еще помню местами. :)


 
VictorT   (2002-04-23 12:56) [15]


> Alx2 © (23.04.02 12:08)

А ты случайно не тот Родионов, что в среде Спектрумовцев в своё время известен был?


 
Alx2   (2002-04-23 13:17) [16]

>VictorT © (23.04.02 12:56)
Нет. В той среде не вращался.
PS
Только Радионов. Такой вот казус :)


 
VictorT   (2002-04-23 13:37) [17]


> Alx2 © (23.04.02 13:17)
> >VictorT © (23.04.02 12:56)

Нда... очетался (наверно таких словов (словей) вообще нет).



Страницы: 1 вся ветка

Текущий архив: 2002.05.06;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.012 c
6-17651
Pat
2002-02-22 00:48
2002.05.06
NMFTP


1-17525
NCR
2002-04-21 22:37
2002.05.06
Вот такая вот проблема: ... Очень надо, просто позарез!


1-17570
HDD
2002-04-22 05:43
2002.05.06
Помогите пожалуйста


1-17596
VJar
2002-04-21 22:44
2002.05.06
Как убрать проект из Alt-Tab в Windows 98???


1-17558
ruslan_as
2002-04-22 10:15
2002.05.06
Ошибка при импорте текстового файла с разделителем