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

Вниз

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

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

Наверх




Память: 0.47 MB
Время: 0.052 c
2-1142259818
MixAnOL
2006-03-13 17:23
2006.03.26
ActiveX


15-1141191738
Ega23
2006-03-01 08:42
2006.03.26
С Днём рождения! 1 марта


8-1129640565
Mirror
2005-10-18 17:02
2006.03.26
слои TIFF


2-1141648909
Dmitrij_K
2006-03-06 15:41
2006.03.26
WebBrowser


6-1133872760
V-A-V
2005-12-06 15:39
2006.03.26
Автологин на прокси сервер





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский