Задание
Операции многократной точности (т.е. операции с длинными числами).
Конкретизация задания
Сначала буквам присваивается значение – например: а=23850934, причем все
переменные – целые числа, которые по длине не должны превышать 300
знаков. Потом пишется выражение, например f=(a+b)/c+(d+a). При этом
деление – это целое от деления делимого на делитель. Операции сложения,
вычитания, умножения – обычные арифметические операции, только это
операции над длинными числами. Кроме сложения, вычитания, умножения и
деления еще могут быть использованы скобки.
Формат ввода
Любую строку в поле ввода можно представить в виде
S={C,V}
Где S – константа либо вычисляемое значение. Если это – константа, то С
– число в строковом виде, перед которым стоит символ «@», а если S надо
найти то S=V, где V – выражение с переменными и числами. В строке не
должно быть пробелов и все переменные состоят из одой буквы. Между
строками в поле ввода не должно быть пустых строк. Вывод идет аналогично
вводу. Пример ввода и вывода можно посмотреть на рисунке
Интерфейс программы.
ных средств разработки на много ускорило процесс написания программы.
Структура хранения
Все длинные числа представляются в виде строки, каждый элемент которой –
цифра. Если число отрицательное, то первым символом строки будет “-“.
Чтобы считать по формуле используем структуру, описанную ниже
type
dd= record
lin:array[1..300] of string;
dl:integer;
end;
var
mas:array[1..300] of dd;
В массиве mas хранится уравнение. Каждый элемент массива – отдельное
уравнение. В lin хранятся отдельные элементы уравнения. Например
mas[3].lin=(‘A’,’=’,’3’,’/’,’(‘,’B’,’-‘,’1’,’)’) соответствует уравнению
A=3/(B-1). В первом элементе (mas[i].lin[1]) всегда хранится буква, во
втором (mas[i].lin[2]) символ “=”. Такая форма ведения уравнения нужна
для удобства вычисления длинных формул. В dl хранится текущее число
элементов в уравнении+1. Можно сказать – если dl=4, то в данном элементе
хранится не формула, которую надо вычислить, а значение.
Количество строк введенных в поле ввода должно быть не более 300 – это
задается размерностью массива mas.
Используемые процедуры и функции
zapolnenie; – заполнение массива mas из поля edt1.
sum(a,b:string):string; – сумма чисел, хранящихся в a и b.
minus(a,b:string):string; – разность чисел, хранящихся в a и b.
minus=a-b
umn(a:integer;var xx:string):string; – умножение числа хх на цифру а.
Используется в функции umnozen.
umnozen(a,b:string):string; – произведение чисел, хранящихся в a и b.
del2(str:string):string; – делит число str на 2.
sravnenie(a,b:string):shortint; – сравнивает число a с числом b.
Возвращается результат:
если а>b, то sravnenie =1
если а
Листинг программы unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type dd= record lin:array[1..300] of string; dl:integer; end; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Label1: TLabel; Label3: TLabel; Memo3: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); function minus(a,b:string):string; function sum(a,b:string):string; procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; mas:array[1..300] of dd; vs1:integer;{elementov v zn} y:integer; {elementov v mas} implementation {$R *.DFM} procedure zapolnenie; var tmp:string; j,nn,ll:integer; chislo:boolean; begin y:=0; for ll:=0 to form1.Memo1.Lines.Count do begin tmp:=form1.Memo1.Lines[ll]; y:=y+1; mas[y].dl:=1; nn:=0; chislo:=false; tmp:=ansiuppercase(tmp); for j:=1 to length(tmp) do begin if tmp[1]='@' then begin mas[y].lin[3]:=copy(tmp,4,300); mas[y].lin[1]:=tmp[2]; mas[y].lin[2]:=tmp[3]; mas[y].dl:=4; break; end else begin mas[y].lin[mas[y].dl]:=copy(tmp,nn+1,j-nn); mas[y].dl:=mas[y].dl+1; nn:=j; end; end; end; end; function TForm1.sum(a,b:string):string; var tmp,c,tmp2:string; i,k,ost,j:integer; bol:boolean; begin if ((b[1]='-') and (a[1]‘-‘)) then begin
sum:=form1.minus(a,copy(b,2,300)); exit;
end;
if ((a[1]=’-‘) and (b[1]‘-‘)) then begin
sum:=form1.minus(b,copy(a,2,300)); exit;
end;
bol:=false;
if ((b[1]=’-‘) and (a[1]=’-‘)) then begin
bol:=true; a:=copy(a,2,300); b:=copy(b,2,300)
end;
if length(b)>length(a) then begin
tmp:=b; b:=a; a:=tmp;
end;
ost:=0;
if length(b)length(a) then b:=’0’+b;
c:=a;
j:=length(a);
tmp2:=”;
for i:=length(b) downto 1 do begin
tmp2:=tmp2+’0′;
k:=strtoint(c[j])+strtoint(b[i]);
k:=k+ost;
ost:=0;
if k>9 then begin
ost:=k div 10; k:=k mod 10;
end;
c[j]:=inttostr(k)[1];
j:=j-1;
end;
if ost>0 then begin
tmp2:=inttostr(ost)+tmp2;
c:=form1.sum(tmp2,c);
end;
if bol then c:=’-‘+c;
sum:=c;
end;
function Tform1.minus(a,b:string):string;
var
i,la,lb,vv,snos:integer;
c,tmp:string;
pom:boolean;
begin
if ((b[1]=’-‘) and (a[1]‘-‘)) then begin
minus:=form1.sum(a,copy(b,2,300)); exit;
end;
if ((a[1]=’-‘) and (b[1]‘-‘)) then begin
minus:=form1.sum(a,’-‘+b); exit;
end;
if ((b[1]=’-‘) and (a[1]=’-‘)) then begin
minus:=form1.minus(copy(b,2,300),copy(a,2,300)); exit;
end;
c:=a;
pom:=false;
la:=length(a); lb:=length(b);
if lb>la then begin
pom:=true; c:=b; b:=a; a:=c;
la:=length(a); lb:=length(b);
end;
snos:=0;
for i:=lb downto 1 do begin
vv:=strtoint(a[la-lb+i])-strtoint(b[i])-snos;
snos:=0;
if vv1)) do c:=copy(c,2,300);
if pom then c:=’-‘+c;
minus:=c;
end;
function umn(a:integer;var xx:string):string;
var
i,ost,tmp,dl:integer;
str:string;
begin
ost:=0;
str:=”;
dl:=length(xx);
for i:=dl downto 1 do begin
tmp:=a*strtoint(xx[i])+ost;
if tmp>9 then begin
str:=inttostr((tmp mod 10))+str;
ost:=tmp div 10;
if i=1 then str:=inttostr(ost)+str;
end
else begin
str:=inttostr(tmp)+str;
ost:=0;
end;
end;
umn:=str;
end;
function umnozen(a,b:string):string;
var
k,i:integer;
tmp,c,r:string;
bol:boolean;
begin
bol:=false;
if ((b[1]=’-‘) and (a[1]‘-‘)) then begin
bol:=true; b:=copy(b,2,300);
end;
if ((a[1]=’-‘) and (b[1]‘-‘)) then begin
bol:=true; a:=copy(a,2,300);
end;
if ((b[1]=’-‘) and (a[1]=’-‘)) then begin
a:=copy(a,2,300); b:=copy(b,2,300)
end;
if ((a=’0′)or(b=’0′)) then begin
umnozen:=’0′; exit;
end;
k:=length(b);
c:=’0′; tmp:=”;
for i:=k downto 1 do begin
r:=umn(strtoint(b[i]),a);
r:=r+tmp;
tmp:=tmp+’0′;
c:=form1.sum(c,r);
end;
if bol then c:=’-‘+c;
umnozen:=c;
end;
function sravnenie(a,b:string):shortint;
{ если а>b, то сравнение=1
если аla then sravnenie:=-1;
if lb
sravnenie:=1;
exit;
end;
if a[i]‘-‘)) then begin
zzz:=true; b:=copy(b,2,300);
end;
if ((a[1]=’-‘) and (b[1]‘-‘)) then begin
zzz:=true; a:=copy(a,2,300);
end;
if ((b[1]=’-‘) and (a[1]=’-‘)) then begin
a:=copy(a,2,300); b:=copy(b,2,300)
end;
bol:=true;
lev:=’0′; prav:=a; pr:=’0’; rab:=a;
if b‘1’ then
while (bol) do begin
tmp:=form1.minus(a,pr);
if tmp[1]=’-‘ then tmp:=copy(tmp,2,300);
if (sravnenie(tmp,del2(b))1) then break;//bol:=false;
tmp:=form1.minus(prav,lev); rab:=”;
rab:=form1.sum(lev,del2(tmp));
pr:=umnozen(b,rab);
if sravnenie(a,pr)=1 then begin
lev:=rab;
end
else begin
prav:=rab;
end;
end;
if zzz then rab:=’-‘+rab;
delen:=rab;
if ((rab=’-‘)or(rab=”))then delen:=’0′;
end;
function po_ch_num(ch:string;var znach:string):boolean;
var
bol:boolean;
i:integer;
begin
bol:=false;
for i:=1 to y do begin
if ((mas[i].dl=4)and(mas[i].lin[1]=ch)) then begin
bol:=true;
znach:=mas[i].lin[3];
end;
end;
po_ch_num:=bol;
end;
function sislo(ch:char):boolean;
begin
if ((ch>=’0’)and(ch0 then begin
k2:=0;
for i:=1 to mas[z].dl-1 do begin
if mas[z].lin[i]='(‘ then k2:=k2+1;
if k2=k then begin
if mas[z].lin[i+2]=’)’ then begin
mas[z].lin[i]:=mas[z].lin[i+1];
for m:=i+1 to mas[z].dl-2 do mas[z].lin[m]:=mas[z].lin[m+2];
mas[z].dl:=mas[z].dl-2;
poisk(z);
exit;
end
else begin
zz:=i+1;
while mas[z].lin[zz]‘)’ do begin
if ((mas[z].lin[zz]=’*’)or(mas[z].lin[zz]=’/’)) then begin
if po_ch_num(mas[z].lin[zz-1],tmp) then
mas[z].lin[zz-1]:=tmp;
if po_ch_num(mas[z].lin[zz+1],tmp) then
mas[z].lin[zz+1]:=tmp;
if
(((sislo(mas[z].lin[zz-1][1])))and(sislo(mas[z].lin[zz+1][1]))) then
begin
zn:=mas[z].lin[zz][1];
if zn=’*’ then
mas[z].lin[zz-1]:=umnozen(mas[z].lin[zz-1],mas[z].lin[zz+1])
else
mas[z].lin[zz-1]:=delen(mas[z].lin[zz-1],mas[z].lin[zz+1]);
for m:=zz to mas[z].dl-2 do
mas[z].lin[m]:=mas[z].lin[m+2];
mas[z].dl:=mas[z].dl-2;
poisk(z);
exit;
end;
end;
zz:=zz+1;
end;
//////// {snachala / i *, potom + i -}
zz:=i+1;
while mas[z].lin[zz]‘)’ do begin
if ((mas[z].lin[zz]=’+’)or(mas[z].lin[zz]=’-‘)) then begin
if po_ch_num(mas[z].lin[zz-1],tmp) then
mas[z].lin[zz-1]:=tmp;
if po_ch_num(mas[z].lin[zz+1],tmp) then
mas[z].lin[zz+1]:=tmp;
if
((sislo(mas[z].lin[zz-1][1]))and(sislo(mas[z].lin[zz+1][1]))) then begin
zn:=mas[z].lin[zz][1];
if zn=’+’ then
mas[z].lin[zz-1]:=form1.sum(mas[z].lin[zz-1],mas[z].lin[zz+1])
else
mas[z].lin[zz-1]:=form1.minus(mas[z].lin[zz-1],mas[z].lin[zz+1]);
for m:=zz to mas[z].dl-2 do
mas[z].lin[m]:=mas[z].lin[m+2];
mas[z].dl:=mas[z].dl-2;
poisk(z);
exit;
end;
end;
zz:=zz+1;
end;
////////
end;
end;
end;
end
else begin {esli skobok net}
for zz:=1 to mas[z].dl-1 do begin if
((mas[z].lin[zz]=’*’)or(mas[z].lin[zz]=’/’)) then begin
if po_ch_num(mas[z].lin[zz-1],tmp) then
mas[z].lin[zz-1]:=tmp;
if po_ch_num(mas[z].lin[zz+1],tmp) then
mas[z].lin[zz+1]:=tmp;
if
((sislo(mas[z].lin[zz-1][1]))and(sislo(mas[z].lin[zz+1][1]))) then begin
zn:=mas[z].lin[zz][1];
if zn=’*’ then
mas[z].lin[zz-1]:=umnozen(mas[z].lin[zz-1],mas[z].lin[zz+1])
else
mas[z].lin[zz-1]:=delen(mas[z].lin[zz-1],mas[z].lin[zz+1]);
for m:=zz to mas[z].dl-2 do
mas[z].lin[m]:=mas[z].lin[m+2];
mas[z].dl:=mas[z].dl-2;
poisk(z);
exit;
end;
end;
end;
for zz:=1 to mas[z].dl-1 do begin
////////
if ((mas[z].lin[zz]=’+’)or(mas[z].lin[zz]=’-‘)) then begin
if po_ch_num(mas[z].lin[zz-1],tmp) then
mas[z].lin[zz-1]:=tmp;
if po_ch_num(mas[z].lin[zz+1],tmp) then
mas[z].lin[zz+1]:=tmp;
if
((sislo(mas[z].lin[zz-1][1]))and(sislo(mas[z].lin[zz+1][1]))) then begin
zn:=mas[z].lin[zz][1];
if zn=’+’ then
mas[z].lin[zz-1]:=form1.sum(mas[z].lin[zz-1],mas[z].lin[zz+1])
else
mas[z].lin[zz-1]:=form1.minus(mas[z].lin[zz-1],mas[z].lin[zz+1]);
for m:=zz to mas[z].dl-2 do
mas[z].lin[m]:=mas[z].lin[m+2];
mas[z].dl:=mas[z].dl-2;
poisk(z);
exit;
end;
end;
///////
end;
end;
end;
procedure vivod;
var
i:integer;
begin
form1.Memo3.Clear;
for i:=1 to y do
if mas[i].dl=4 then begin
form1.Memo3.Lines.Add(mas[i].lin[1]+’=’+mas[i].lin[3]);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:integer;
begin
zapolnenie;
for j:=1 to y do
for i:=1 to y do poisk(i);
vivod;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
messagedlg(‘Iia?aoeee iiiaie?aoiie oi/iinoe’,mtinformation,[mbok],0);
end;
end.
PAGE
PAGE 4
Ввод a,b
Bol=false
b=0
b=-b
bol=true
да
нет
нет
да
a=-a
bol=true
a=0
нет
да
b=-b
a=-a
a=1
да
r=umn(b[k],a)
r=r+tmp
tmp:=tmp+’0’
c=sum(c,r)
k=k-1
нет
bol=true
да
c=’-‘+c
нет
umnozen=c
Выход
Нашли опечатку? Выделите и нажмите CTRL+Enter