Страница 1 из 1

Найти 1 производную

Добавлено: 21 мар 2009, 02:30
dr.Jekill
Читаем выражение из файла в префиксной форме, формируем дерево выражения и выводим в разных(для наглядности) формах. Файл может называться от ex1.in до exN.in. Каждая строка одна константа, переменная X или оператор. Например, содержимое файла:
cos
+
cos
sin
x
ln
cos
-
-105
sin
x

Вкладываю один файл (надо сменить расширение на .in)

Код: Выделить всё

uses Crt;
type TreePointer = ^tree;
 tree = record
 data: string;
 left: TreePointer;
 right: TreePointer;
end;

var
root:TreePointer;
fail,rez:text;
nom:byte;
ns,name,put:string;

procedure Build(var p:TreePointer);
begin
 new(p);
 readln(fail,p^.data);
 if (p^.data ='+') or (p^.data='-') or (p^.data ='*') or (p^.data ='/') then
  begin
   Build(p^.left);
   Build(p^.right);
  end
  else
  if (p^.data='exp') or (p^.data ='ln') or (p^.data ='cos') or (p^.data ='sin') then
   begin
    p^.left:= nil;
    Build(p^.right);
   end
   else
    begin
     p^.left:= nil;
     p^.right:= nil;
    end
end;

procedure Infix(r:TreePointer);
 begin
  if r<>nil then
   begin
    Infix(r^.left);
    Write(r^.data);
    Infix(r^.right);
   end;
end;

procedure Prefix(r:TreePointer);
 begin
  if r<>nil then
   begin
    Write(r^.data);
    Prefix(r^.left);
    Prefix(r^.right);
   end;
 end;

procedure Postfix(r:TreePointer);
 begin
  if r<>nil then
   begin
    Postfix(r^.left);
    Postfix(r^.right);
    Write(r^.data);
   end;
 end;

begin
 clrscr;
 root := nil;
 write('Vvedite nomer faila s vhodnyni dannymi: ');
 readln(nom);
 str(nom,ns);
 name:='ex'+ns+'.in';
 clrscr;
 writeln('Fail: ',name);
 writeln('Vvedite put k failu,esli on nahoditsia ne v papke s programmoi: ');
 readln(put);
 if length(put)>0 then
  begin
   name:=put+name;
   clrscr;
   writeln('Fail: ',name);
   readln;
  end;
 assign(fail,name);
 reset(fail);
 if eof(fail)=true then
  begin
   writeln('Fail pust!');
   readln;
  end;
 while eof(fail)=false do Build(root);
 writeln('Priamoi obhod: ');
 Prefix(root);
 writeln;
 writeln('Obratnyi obhod: ');
 Postfix(root);
 writeln;
 writeln('Simmetrichnyi obhod: ');
 Infix(root);
 readln;
end.
С этим всё нормально. А дальше:
"Найти производную выражения:
* D(число) = число_0
* D(переменная_x) = переменная_1
* D(A + B) = D(A) + D(B)
* D(A - B) = D(A) - D(B)
* D(A * B) = D(A) * B + A * D(B)
* D(A / B) = (D(A) * B - A * D(B)) / (B * B)
* D(exp A) = (exp A) * D(A)
* D(ln A) = (число_1 / A) * D(A)
* D(sin A) = (cos A) * D(A)
* D(cos A) = (число_0 - sin A) * D(A)
Важно, чтобы программа считала производную именно так, не стоит ничего упрощать или менять порядок подвыражений.
Результатом должна быть структура указателей, описанная так ,как предыдущая. Но теперь это не обязательно должно быть дерево. Если с правой стороны равенства находятся подвыражения исходного выражения, то не стоит создавать в памяти новых узлов, а использовать уже существующие. В частности, это относится ко всему выражению exp(A). Программа должна считать производную в линейном времени – нужно только раз (конкретное число раз) проходить по определенному фрагменту дерева (чтобы это было возможно, фрагменты, которые выступают несколько раз, должны быть «подцеплены» в нескольких местах)".
Не до конца понимаю задание. Может кто поможет разобраться?

Re: Найти 1 производную

Добавлено: 15 апр 2009, 12:31
_drug_
Как я понял, необходимо произвести анализ входного выражения на соответствие структурам в задании слева и сопоставить им структуры справа. Т.е. если исходное выражение (обычная нотация):
y = 2*cos(x) + 4
то программа должна определить:
D(y) = D(2*cos(x) + 4) = D(2*cos(x)) + D(4)=
=D(2)*cos(x) + 2*D(cos(x)) + D(4) =
= D(2)*cos(x) + 2*((0 - sin x) * D(x)) + D(4) =
= D(2)*cos(x) - 2*sin(x) * D(x)) + D(4)
т.к. D(2) = 0, D(4) = 0, D(x) = 1 получается
D(y) = -2*sin(x)

а в целях экономии памяти и не только, если у вас уже есть полученный ранее узел содеражащий -sin(x), то нужно использовать его, а не создавать новый.

как-то так. Или Вы имели в виду что-то другое?

Re: Найти 1 производную

Добавлено: 16 апр 2009, 18:44
dr.Jekill
Уже все готово. Могу выложить исходники если кому-то нужно.

Re: Найти 1 производную

Добавлено: 26 май 2009, 22:37
ronayt
выложи )
мне интересно посмотреть как это логически записать)