создаешь массив (dstv[1..4] of char) инициируешь их как '*','/','+','-'
пишешь процедуру, которая определяет операнды действия: 2+3*4
У '*' операнды: 3,4
У '+' операнды: 2,7
процедура выглядит так: procedure get_operadns(s:string;dstv:integer;var o1,o2:string;var n,k:integer);
параметры процедуры:
s - строка, в которой определяешь операнды
dstv - позиция символа действия, т.е. для примера 2+2*2 позиция символа первого действия = 4
o1,o2 - через них должны вернуться операнды в виде строк (или сразу делай их типом integer или real)
n - позиция начала первого операнда
k - позиция конца второго операнда
Операнды определяются достаточно просто: идешь в левую (и в правую) сторону от номера символа dstv до тех пор пока не найдешь:
1) знак другого действия
2) конец строки
3) начало строки
Код использования в красивом виде будет выглядеть примерно так:
Код:
var o1,o2:string;
n,k:integer;
str:real;
s:='2+2*2';
dstv[1]:='*';
dstv[2]:='/';
dstv[3]:='+';
dstv[4]:='-';
for i:=1 to 4 do
begin
if pos(dstv[i],s)>0 then
begin
//найдено какое-либо действие
get_operands(s,pos(dstv[i],s),o1,o2,n,k);
case dstv[i] of
'+': str:=strtofloat(o1)+strtofloat(o2);
'-': str:=strtofloat(o1)-strtofloat(o2);
'*': str:=strtofloat(o1)*strtofloat(o2);
'/': str:=strtofloat(o1)/strtofloat(o2);
end;
delete(s,n,k-n+1);
insert(floattostr(str),s,n);
end;
end;
Оговорки:
1) Действие '-' лучше не учитывать... лучше рассматривать как действие с отрицательным числом
2) Код достаточно легко можно доработать до учитывания скобок () (делается рекурсией), по аналогии с разбитием действий можно доработать всякие функции (sin,cos.tg....)
3) Как можно понять функция get_operands - самая важная во всем этом деле... потому оставляю её тебе) - ибо похоже что она частично у тебя уже написана
P.S. если дополнить её (так чтобы она не всегда искала два операнда) - можно будет потом влепить её при определении операндов для мат. функций.
4) При использовании get_operand реально имеет смысл сразу возвращать числовой тип данных, и при этом: делать проверку перед конвертированием числа, что там не оказалось хлама... т.е. s='123fff' - при конверте =вылет, s='' - при конверте вылет, s='1.23' - при конверте = вылет (потому что разделителем целой и дробной частей в Delphi является
запятая), в случае написания в Pascal = задача в разы усложняется, но для конверта можно будет использовать раздельное преобразование и соответственно сам определишь каким символом будут отделяться части (целой от дробной: хоть '.', хоть ',', хоть '#')