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

Вниз

Нет ли у кого ф-ии для подсчета значения выражения   Найти похожие ветки 

 
DelphiN! ©   (2006-03-02 08:40) [0]

Нужна ф-ия для подсчета значения выражения(например : "(100 / 2) - (50 / 2)"). Писать самому такое долго, может где есть готовый вариант?

Нужно чтобы работало со скобками, знала знаки *,/,+,-.


 
TUser ©   (2006-03-02 09:05) [1]

> Писать самому такое долго

Алгоритм Дейкстры для этого есть - на час работы максимум.


 
DelphiN! ©   (2006-03-02 09:24) [2]

Действительно, работы на 20 минут было, вот что получилось, кому интересно:


function TForm1.Calc(CalcString: String; Varibles,VariblesValues: TStringList): Real;

function ExtractWorlds(str:String;razdelitel:String): String;
var
 s:string;
 strl:String;
begin
 while pos(razdelitel,str)>0 do
 begin
   if strl <> "" then
     strl := strl+#13#10;
   strl := strl+Copy(str,1,pos(razdelitel,str)-1);
   Delete(str,1,pos(razdelitel,str)+Length(razdelitel)-1);
 end;
 if str <> "" then
 begin
   if strl <> "" then
     strl := strl+#13#10;
   strl := strl+str;
 end;
 ExtractWorlds := strl;
end;

function GetValue(MathString: String): Real;
var
 strl: TStringList;
 i: Integer;
 isZnak: Boolean;
 LastZnack: String;
begin
 try
   strl := TStringList.Create;
   strl.Text := ExtractWorlds(MathString," ");
   i := 0;
   isZnak := false;
   while i < strl.Count do
   begin
     if IsZnak then
       LastZnack := strl.Strings[i]
     else
     begin
       if LastZnack <> "" then
       begin
         if LastZnack = "+" then
           Result := Result+StrToFloat(strl.Strings[i])
         else
         if LastZnack = "-" then
           Result := Result-StrToFloat(strl.Strings[i])
         else
         if LastZnack = "*" then
           Result := Result*StrToFloat(strl.Strings[i])
         else
         if LastZnack = "/" then
           Result := Result/StrToFloat(strl.Strings[i])
         else
         Result := StrToFloat(strl.Strings[i]);
       end
       else
         Result := StrToFloat(strl.Strings[i]);
     end;

     isZnak := not isZnak;
     Inc(i);
   end;

 finally
   strl.Free;
 end;
end;

var
 i,j: Integer;
 str: String;
 IsOpen: Boolean;
 OpenN,CloseN: Integer;
begin
 //Заменить название переменных их значенияи
 for i := 0 to Varibles.Count-1 do
 begin
   j := pos(AnsiUpperCase(Varibles.Strings[i]),AnsiUpperCase(CalcString));
   while j > 0 do
   begin
     Delete(CalcString,j,Length(Varibles.Strings[i]));
     Insert(VariblesValues.Strings[i],CalcString,j);
     j := pos(AnsiUpperCase(Varibles.Strings[i]),AnsiUpperCase(CalcString));
   end;
 end;
 //Заменить выражения в скобках их значениями
 i := 1;
 IsOpen := false;
 while i < Length(CalcString) do
 begin
   if CalcString[i] = "(" then
   begin
     OpenN := i;
     str := "";
     IsOpen := true;
     Inc(i);
   end
   else
   if CalcString[i] = ")" then
   begin
     CloseN := i;
     Delete(CalcString,OpenN,(CloseN-OpenN)+1);
     Insert(FloatToStr(GetValue(str)),CalcString,OpenN);
     str := "";
     IsOpen := false;
     i := 0;
   end;
   if IsOpen then
     str := str+CalcString[i];
   Inc(i);
 end;
 //Вывести конечный результат
 Result := GetValue(CalcString);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Varibles,Values: TStringList;
 CalcStr: String;
begin
 try
   Varibles := TStringList.Create;
   Values := TStringList.Create;
   Varibles.Add("Screen.Width");
   Values.Add(IntToStr(Screen.Width));
   CalcStr := "(Screen.Width / 2) + 100";
   Edit1.Text := (FloatToStr(Calc(CalcStr,Varibles,Values)));
 finally
   Varibles.Free;
   Varibles.Free;
 end;
end;


Ф-ия работает со скобками, переменными, и распознает знаки *,\,+,-.
Правда не соблюдает правила, что умножение и деление считается в первую очередь, но благодоря скобкам этим можно пренебречь


 
DelphiN! ©   (2006-03-02 09:42) [3]

Сорри, ошибочку нашел :

 while i < Length(CalcString) do
заменить на
 while i <= Length(CalcString) do


 
wicked ©   (2006-03-02 10:40) [4]


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


 
Kerk ©   (2006-03-02 10:42) [5]

На http://kladovka.net.ru дофига такого добра.


 
DelphiN! ©   (2006-03-02 11:05) [6]


>  [4] wicked ©   (02.03.06 10:40)


Не смотрел еще этот алгоритм, а вообще мне это не надо просто, так то подставить скобки при нахождении знака *,\ труда думаю не составит.


>  [5] Kerk ©   (02.03.06 10:42)


Буду знать теперь где искать в первую очередь!


 
TUser ©   (2006-03-02 11:25) [7]

> Буду знать теперь где искать в первую очередь!

http://algolist.manual.ru/


 
DelphiN! ©   (2006-03-02 11:58) [8]


>  [7] TUser ©   (02.03.06 11:25)


А за это вообще БОЛЬШОЙ ПАСИБ!



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

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

Наверх




Память: 0.49 MB
Время: 0.047 c
15-1141064916
Matrex
2006-02-27 21:28
2006.03.26
Опрос. Работа с мобильным телефоном (Siemens) – быть или не быть…


2-1141993956
fedpavel
2006-03-10 15:32
2006.03.26
DLL


2-1141169056
spogi
2006-03-01 02:24
2006.03.26
Kak v QReport pokazat dannie iz raznix tablic, ili summirovat ix


2-1142153436
ArhangelX
2006-03-12 11:50
2006.03.26
Как разложить byte на биты


15-1141599465
Andy BitOff
2006-03-06 01:57
2006.03.26
Помогите понять код на С