Скачиваний:
7
Добавлен:
01.05.2014
Размер:
476.16 Кб
Скачать

Листинг основного модуля.

unit TreeForD;

interface

Uses Crt, Inform;

var

Table: cMas;

procedure Create(var Root:pTree);

procedure DrawTreeF(var H : Text; var Root:pTree; var OpM : uMas; var CoM: cMas; Deg:Integer);

procedure DrawTree(var Root:pTree; var OpM : uMas; var CoM: cMas; Deg:Integer);

procedure FillStartCond(var Root:pTree; var OpM: uMas; var CoM : cMas;ActX: String);

procedure MakeTree(var Root : pTree; var OpM : uMas; var I,J: integer);

function Derivate(var H : Text; var Root : pTree; var OpM: uMas; var CoM : cMas):Boolean;

implementation

procedure Create(var Root:pTree);

begin

New(Root);

Root := Nil

end;

function FindMin(var OpM: uMas; I,J: Integer):Integer;

var

P,Rec: Integer;

begin

rec := I;

For P := I to J do

If OpM[P].Prior <= OpM[Rec].Prior then

Rec := P;

FindMin := Rec

end;

procedure FormCodeTable(var Tab : cMas);

begin

Tab[2] := '+';

Tab[3] := '-';

Tab[4] := '*';

Tab[5] := '/';

Tab[6] := 'sin';

Tab[7] := 'cos';

Tab[8] := 'asi';

Tab[9] := 'atg';

Tab[10] := 'log';

Tab[11] := 'exp';

Tab[16] := '^'

end;

procedure MakeTree(var Root : pTree; var OpM : uMas; var I,J: integer);

var

P : Integer;

begin

If I = J then

begin

New(Root);

Root^.code := I;

Root^.left := nil;

Root^.right := nil;

end

else

begin

P := FindMin(OpM,I,J);

New(Root);

Root^.left := NIl;

Root^.Code := P;

P := P + 1;

MakeTree(Root^.right,OpM,P,J);

P := P - 1;

If (OpM[P].Op.Code < 6) or (OpM[P].Op.Code > 11) then

begin

P := P - 1;

MakeTree(Root^.left,OpM,I,P)

end

end

end;

procedure FindEnd(var Root,Pointer : pTree);

begin

If Root^.Left <> nil then

If (Root^.left^.left <> Nil) or (Root^.left^.right <> Nil) then

FindEnd(Root^.left,Pointer)

else

If (Root^.Right^.left <> Nil) or (Root^.Right^.Right <> Nil) then

FindEnd(Root^.Right,Pointer)

else

Pointer := Root

else

If (Root^.Right^.left <> Nil) or (Root^.Right^.Right <> Nil) then

FindEnd(Root^.Right,Pointer)

else

Pointer := Root

end;

procedure Push(var from,where: tStr;Start:Integer);

var

I : Integer;

begin

where.Len := From.Len + Start - 1;

For I := 1 to From.Len do

Where.S[I + Start - 1] := From.S[I]

end;

function Zero(var S : tStr):Boolean;

begin

If (S.len = 1) and (S.S[1] = '0') then

Zero := true

else

Zero := false

end;

function One(var S : tStr):Boolean;

begin

If (S.len = 1) and (S.S[1] = '1') then

One := true

else

One := false

end;

function mOne(var S : tStr):Boolean;

begin

If (S.len = 2) and (S.S[1] = '-') and (S.S[2] = '1') then

mOne := true

else

mOne := false

end;

function Equil(var S1,S2 : tStr): Boolean;

var

I : Integer;

E : Boolean;

begin

E := false;

If S1.Len = S2.Len then

begin

For I := 1 to S1.Len do

If S1.S[I] <> S2.S[I] then

E := true

end

else

E := true;

Equil := not(E)

end;

function InOp(var A: tStr):Boolean;

var

I : Integer;

E : Boolean;

begin

E := false;

I := 1;

while (I <= A.Len) and not(E) do

begin

If (A.S[I] = '+') or (A.S[I] = '-') then

E := true;

I := I + 1

end;

InOp := E

end;

procedure Sum(var S1,S2,A : tStr);

begin

If Zero(S1) and not(Zero(S2)) then

Push(S2,A,1)

else If Zero(S2) and not(Zero(S1)) then

Push(S1,A,1)

else If Zero(S1) and Zero(S2) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

If (One(S1) and mOne(S2)) or (mOne(S1) and One(S2)) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

begin

If Equil(S1,S2) then

If InOp(S1) then

begin

A.S[1] := '2';

A.S[2] := '*';

A.S[3] := '(';

Push(S1,A,4);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1

end

else

begin

A.S[1] := '2';

A.S[2] := '*';

Push(S1,A,3)

end

else

begin

Push(S1,A,1);

A.S[S1.Len + 1] := '+';

Push(S2,A,S1.Len + 2)

end

end;

end;

function InOp2(var A : tStr):Boolean;

var

I : Integer;

E : Boolean;

begin

E := false;

I := 1;

while (I <= A.Len) and not(E) do

begin

If (A.S[I] = '+') or (A.S[I] = '-') or (A.S[I] = '*') or (A.S[I] = '/') then

E := true;

I := I + 1

end;

InOp2 := E

end;

function InOp3(var A : tStr):Boolean;

begin

InOp3 := not(A.Len = 1)

end;

procedure Minus(var S1,S2,A : tStr);

begin

If Zero(S1) and not(Zero(S2)) then

begin

A.S[1] := '-';

If InOp(S2) then

begin

A.S[2] := '(';

Push(S2,A,3);

A.S[S2.len + 3] := ')';

A.len := A.len + 1

end

else

Push(S2,A,2)

end

else If Zero(S2) and not(Zero(S1)) then

Push(S1,A,1)

else If Zero(S1) and Zero(S2) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

If (One(S1) and One(S2)) or (mOne(S1) and mOne(S2)) then

begin

A.Len := 1;

A.S[1] := '0';

end

else

begin

If Equil(S1,S2) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

begin

Push(S1,A,1);

A.S[S1.Len + 1] := '-';

If InOp(S2) then

begin

A.S[S1.len + 2] := '(';

Push(S2,A,S1.Len + 3);

A.S[S1.Len + S2.Len + 3] := ')';

A.Len := A.Len + 1

end

else

Push(S2,A,A.Len + 2)

end

end;

end;

procedure Mult(var S1,S2,A : tStr);

var

I : Integer;

begin

If Zero(S1) or Zero(S2) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

If One(S1) then

Push(S2,A,1)

else

If One(S2) then

Push(S1,A,1)

else

If mOne(S1) and not(mOne(S2)) then

begin

A.S[1] := '-';

If InOp(S2) then

begin

A.S[2] := '(';

Push(S2,A,3);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S2,A,2)

end

else

If mOne(S2) and not(mOne(S1)) then

begin

A.S[1] := '-';

If InOp(S1) then

begin

A.S[2] := '(';

Push(S1,A,3);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S1,A,2)

end

else

If mOne(S1) and mOne(S2) then

begin

A.Len := 1;

A.S[1] := '1'

end

else

begin

If Equil(S1,S2) then

begin

If InOp2(S1) then

begin

A.S[1] := '(';

Push(S1,A,2);

A.S[A.Len + 1] := ')';

A.S[A.Len + 2] := '^';

A.S[A.Len + 3] := '2';

A.Len := A.Len + 3

end

else

begin

Push(S1,A,1);

A.S[A.Len + 1] := '^';

A.S[A.Len + 2] := '2';

A.Len := A.Len + 2

end

end

else

begin

If InOp(S1) then

begin

A.S[1] := '(';

Push(S1,A,2);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S1,A,1);

A.S[A.Len + 1] := '*';

A.Len := A.Len + 2;

If InOp(S2) then

begin

A.S[A.Len] := '(';

Push(S2,A,A.len + 1);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S2,A,A.Len)

end

end

end;

function Diviz(var S1,S2,A : tStr):Boolean;

begin

If Zero(S2) then

begin

clrscr;

writeln('Divizion by zero!');

readkey;

Diviz := false

end

else

begin

If Zero(S1) then

begin

A.Len := 1;

A.S[1] := '0';

end

else

If One(S2) then

Push(S1,A,1)

else

If One(S1) then

begin

A.S[1] := '1';

A.S[2] := '/';

If InOp2(S2) then

begin

A.S[3] := '(';

Push(S2,A,4);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S2,A,3)

end

else

If mOne(S2) and not(mOne(S1)) then

begin

A.S[1] := '-';

If InOp2(S1) then

begin

A.S[2] := '(';

Push(S1,A,3);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S1,A,2)

end

else

If mOne(S2) and mOne(S1) then

begin

A.Len := 1;

A.S[1] := '1'

end

else

begin

If Equil(S1,S2) then

begin

A.Len := 1;

A.S[1] := '1'

end

else

begin

If InOp2(S1) then

begin

A.S[1] := '(';

Push(S1,A,2);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1;

end

else

Push(S1,A,1);

A.S[A.Len + 1] := '/';

If InOp2(S2) then

begin

A.S[A.Len + 2] := '(';

Push(S2,A,A.Len + 3);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end

else

Push(S2,A,A.Len + 2)

end

end;

Diviz := true;

end

end;

function Deg(var S1,S2,A : tStr):Boolean;

var

K : tStr;

E : Boolean;

begin

E := true;

If Zero(S1) then

If not Zero(S2) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

E := false

else

If mOne(S1) then

E := False

else

If Zero(S2) or One(S1) then

begin

A.Len := 1;

A.S[1] := '1'

end

else

If One(S2) then

Push(S1,A,1)

else

If mOne(S2) then

begin

K.Len := 1;

K.S[1] := '1';

If not(Diviz(K,S1,A)) then

E := false

end

else

begin

If InOp2(S1) then

begin

A.S[1] := '(';

Push(S1,A,2);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1

end

else

Push(S1,A,1);

A.S[A.Len + 1] := '^';

If InOp2(S2) then

begin

A.S[A.Len + 2] := '(';

Push(S2,A,A.Len + 3);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1

end

else

Push(S2,A,A.Len + 2)

end

end;

function Derivate(var H : Text; var Root : pTree; var OpM: uMas; var CoM : cMas):Boolean;

var

P : pTree;

F,G,F1,G1,A,dA,K,L,N,T : tStr;

I : Integer;

Error : Boolean;

begin

Error := false;

while (Root^.Right <> Nil) and not(Error) do

begin

FindEnd(Root,P);

If P^.left <> Nil then

begin

F := P^.left^.Func;

F1 := P^.left^.Der

end;

G := P^.right^.Func;

G1 := P^.right^.der;

If OpM[P^.Code].Op.Code = 2 then

begin

Sum(F,G,A);

Sum(F1,G1,dA)

end;

If OpM[P^.Code].Op.Code = 3 then

begin

Minus(F,G,A);

Minus(F1,G1,dA)

end;

If OpM[P^.Code].Op.Code = 4 then

begin

Mult(F,G,A);

Mult(F1,G,K);

Mult(G1,F,L);

Sum(K,L,dA)

end;

If OpM[P^.Code].Op.Code = 5 then

begin

If Diviz(F,G,A) then

begin

Mult(F1,G,K);

Mult(G1,F,L);

Minus(K,L,T);

Mult(G,G,K);

If not(Diviz(T,K,dA)) then

Error := true

end

else

Error := true

end;

If OpM[P^.Code].Op.Code = 6 then

begin

If Zero(G) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

begin

A.S[1] := 's';

A.S[2] := 'i';

A.S[3] := 'n';

A.S[4] := '(';

Push(G,A,5);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end;

If Zero(G1) then

begin

K.Len := 1;

K.S[1] := '1'

end

else

begin

K.S[1] := 'c';

K.S[2] := 'o';

K.S[3] := 's';

K.S[4] := '(';

Push(G,K,5);

K.Len := K.Len + 1;

K.S[K.Len] := ')'

end;

Mult(K,G1,dA)

end;

If OpM[P^.Code].Op.Code = 7 then

begin

If Zero(G) then

begin

A.Len := 1;

A.S[1] := '1'

end

else

begin

A.S[1] := 'c';

A.S[2] := 'o';

A.S[3] := 's';

A.S[4] := '(';

Push(G,A,5);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end;

If Zero(G1) then

begin

K.Len := 1;

K.S[1] := '0'

end

else

begin

K.S[1] := '-';

K.S[2] := 's';

K.S[3] := 'i';

K.S[4] := 'n';

K.S[5] := '(';

Push(G,K,6);

K.Len := K.Len + 1;

K.S[K.Len] := ')'

end;

Mult(K,G1,dA)

end;

If OpM[P^.Code].Op.Code = 8 then

begin

If Zero(G) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

If mOne(G) then

begin

A.Len := 5;

A.S[1] := '-';

A.S[2] := 'P';

A.S[3] := 'i';

A.S[4] := '/';

A.S[5] := '2'

end

else

If One(G) then

begin

A.Len := 4;

A.S[2] := 'P';

A.S[3] := 'i';

A.S[4] := '/';

A.S[5] := '2'

end

else

begin

A.S[1] := 'a';

A.S[2] := 's';

A.S[3] := 'i';

A.S[4] := '(';

Push(G,A,5);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end;

If Zero(G) then

begin

K.Len := 1;

K.S[1] := '1'

end

else

If One(G) or mOne(G) then

begin

K.Len := 1;

K.S[1] := '0'

end

else

begin

Mult(G,G,L);

N.Len := 1;

N.S[1] := '1';

Minus(N,L,T);

L.Len := 3;

L.S[1] := '0';

L.S[2] := '.';

L.S[3] := '5';

If not(Deg(T,L,K)) then

Error := true

end;

If not(Diviz(G1,K,dA)) then

Error := true

end;

If OpM[P^.Code].Op.Code = 9 then

begin

If Zero(G) then

begin

A.Len := 1;

A.S[1] := '0'

end

else

If One(G) then

begin

A.Len := 4;

A.S[1] := 'P';

A.S[2] := 'i';

A.S[3] := '/';

A.S[4] := '4'

end

else

If mOne(G) then

begin

A.Len := 5;

A.S[1] := '-';

A.S[2] := 'P';

A.S[3] := 'i';

A.S[4] := '/';

A.S[5] := '4'

end

else

begin

A.S[1] := 'a';

A.S[2] := 't';

A.S[3] := 'g';

A.S[4] := '(';

Push(G,A,5);

A.Len := A.Len + 1;

A.S[A.Len] := ')'

end;

If Zero(G) then

begin

K.Len := 1;

K.S[1] := '1'

end

else

begin

Mult(G,G,L);

N.Len := 1;

N.S[1] := '1';

Sum(N,L,K)

end;

If not(Diviz(G1,K,dA)) then

Error := true

end;

If OpM[P^.Code].Op.Code = 10 then

begin

If (Zero(G) or mOne(G)) then

begin

clrscr;

writeln('Impossible for lg...');

readkey;

Error := true

end

else

If One(G) then

begin

A.len := 1;

A.S[1] := '0'

end

else

begin

A.S[1] := 'l';

A.S[2] := 'o';

A.S[3] := 'g';

A.S[4] := '(';

Push(G,A,5);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1

end;

If not(Diviz(G1,G,dA)) then

Error := true

end;

If OpM[P^.Code].Op.Code = 11 then

begin

If Zero(G) then

begin

G.Len := 1;

G.S[1] := '1'

end

else

If One(G) then

begin

G.Len := 1;

G.S[1] := 'E'

end

else

If mOne(G) then

begin

G.Len := 3;

G.S[1] := '1';

G.S[2] := '/';

G.S[3] := 'E'

end

else

begin

A.S[1] := 'e';

A.S[2] := 'x';

A.S[3] := 'p';

A.S[4] := '(';

Push(G,A,5);

A.S[A.Len + 1] := ')';

A.Len := A.Len + 1

end;

Mult(G1,A,dA)

end;

If OpM[P^.Code].Op.Code = 16 then

begin

If Deg(F,G,A) then

begin

If Zero(F) or mOne(F) then

begin

clrscr;

writeln('Impossible for degree...');

readkey;

Error := true

end

else

If One(F) then

begin

L.Len := 1;

L.S[1] := '0'

end

else

begin

L.S[1] := 'l';

L.S[2] := 'o';

L.S[3] := 'g';

L.S[4] := '(';

Push(F,L,5);

L.S[L.Len + 1] := ')';

L.Len := L.Len + 1

end;

Mult(G1,L,K);

Mult(F1,G,N);

If Diviz(N,F,T) then

begin

Sum(K,T,L);

mult(A,L,dA)

end

else

Error := true

end

else

Error := True

end;

P^.left := Nil;

P^.Right := Nil;

{Dispose(P^.left);

Dispose(P^.Right);}

clrscr;

If not(Error) then

begin

P^.func := A;

P^.der := dA;

writeln(H);

writeln(H);

writeln;

writeln;

writeln(H,'The operation tree is:');

writeln('The operation tree is: ');

writeln(H);

writeln(H);

writeln;

writeln;

DrawTreeF(H,Root,OpM,CoM,0);

DrawTree(Root,OpM,CoM,0);

readkey

end

end;

Derivate := not(Error)

end;

procedure DrawSpaceF(var H: Text; Deg : Integer);

var

K : Integer;

begin

If Deg > 0 then

for K := 1 to Deg do

write(H,' ');

end;

procedure DrawTreeF(var H : Text; var Root:pTree; var OpM : uMas; var CoM: cMas; Deg:Integer);

var

I : Integer;

begin

If Root<>Nil then

begin

DrawTreeF(H,Root^.Right,OpM,CoM,deg+1);

DrawSpaceF(H,Deg);

write(H,' ');

TextColor(Red);

For I := 1 to Root^.func.Len do

write(H,Root^.func.S[I]);

TextColor(white);

writeln(H);

DrawSpaceF(H,Deg);

If OpM[Root^.Code].Op.Num = false then

writeln(H,Table[OpM[Root^.Code].Op.Code])

else

writeln(H,CoM[Root^.Code]);

DrawSpaceF(H,Deg);

write(H,' ');

TextColor(Blue);

For I := 1 to Root^.der.Len do

write(H,Root^.der.S[I]);

writeln(H);

DrawTreeF(H,Root^.left,OpM,CoM,deg+1);

TextColor(white)

end

else If Deg = 0 then

writeLn(H,'The Tree is empty...')

end;

procedure DrawSpace(Deg : Integer);

var

K : Integer;

begin

If Deg > 0 then

for K := 1 to Deg do

write(' ');

end;

procedure DrawTree(var Root:pTree; var OpM : uMas; var CoM: cMas; Deg:Integer);

var

I : Integer;

begin

If Root<>Nil then

begin

DrawTree(Root^.Right,OpM,CoM,deg+1);

DrawSpace(Deg);

write(' ');

TextColor(Red);

For I := 1 to Root^.func.Len do

write(Root^.func.S[I]);

TextColor(white);

writeln;

DrawSpace(Deg);

If OpM[Root^.Code].Op.Num = false then

writeln(Table[OpM[Root^.Code].Op.Code])

else

writeln(CoM[Root^.Code]);

DrawSpace(Deg);

write(' ');

TextColor(Blue);

For I := 1 to Root^.der.Len do

write(Root^.der.S[I]);

writeln;

DrawTree(Root^.left,OpM,CoM,deg+1);

TextColor(white)

end

else If Deg = 0 then

writeLn('The Tree is empty...')

end;

procedure Move(S : String; var tS : tStr);

var

H : Text;

C : Char;

begin

assign(H,'H.txt');

rewrite(H);

write(H,S);

reset(H);

tS.Len := 0;

while not Eof(H) do

begin

read(H,C);

tS.Len := tS.Len + 1;

tS.S[tS.Len] := C

end;

close(H)

end;

procedure FillStartCond(var Root:pTree; var OpM: uMas; var CoM : cMas;ActX: String);

var

T : pTree;

begin

T := Root;

If T^.left <> Nil then

FillStartCond(T^.Left,OpM,CoM,ActX);

If T^.Right <> Nil then

FillStartCond(T^.Right,OpM,CoM,ActX);

T^.Func.Len := 0;

T^.der.Len := 0;

If (T^.Right = Nil)and(T^.Left = Nil)and(OpM[T^.Code].Op.Num = true) then

begin

Move(CoM[T^.Code],T^.Func);

T^.Der.Len := 1;

If CoM[T^.Code] = ActX then

T^.der.S[1] := '1'

else

T^.der.S[1] := '0'

end

end;

begin

FormCodeTable(Table);

end.

Соседние файлы в папке Аналитическое дифференцирование