Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.05.06;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.005 c
1-17517
ATLANTIDO
2002-04-23 15:28
2002.05.06
Контроль времени


14-17697
MBo
2002-03-29 16:16
2002.05.06
Заинтересовался вот.


4-17733
Cobalt
2002-02-27 15:19
2002.05.06
Доступ к чужим окнам


14-17677
SPeller
2002-03-22 14:26
2002.05.06
Глупый вопрос..


1-17516
VictorSV
2002-04-23 11:00
2002.05.06
Модальные окна





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский