Программа


PROGRAM PolyMan;
USES CRT;  { Подключение модуля CRT }
TYPE BasePoly=^Add; { Ссылка на слагаемое }
     Add=record  { Слагаемое полинома }
           Power:word; { Степень переменных }
           X,Y,Z:real; { Множители при X, Y, Z }
           Next:BasePoly
         end;
     FullPoly=record   { Тип - полином }
                Poly:BasePoly; { Ссылка на слагаемые с не нулевой степенью }
                Free:real;     { Свободный элемент }
              end;
FUNCTION Question(S:string):boolean; { Функция получения ответа на вопрос }
  Var Ch:char;                       { Буфер }
  Begin
    repeat
      Write(S,' [Y/N] ');   { Вывод вопроса }
      ReadLn(Ch) { Ввод символа }
    until Ch in ['Y','y','N','n'];
                           { Выход из цикла при получении корректного ответа }
    Question:=Ch in ['Y','y'] { Определение значения функции }
  End;
PROCEDURE DisposerList(var L:BasePoly); { Процедура удаления списка }
  Begin
    if L<>nil then begin   { Если переменная существует, то }
                     DisposerList(L^.NEXT);  { удаление хвоста списка }
                     Dispose(L);             { удаление переменной }
                     L:=nil { Переопределение ссылки }
                   end
  End;
PROCEDURE InputPoly(var Poly:FullPoly); { Процедура ввода полинома }
  Var n,nNew:word; { Счетчики степени }
      Ref,PredRef:BasePoly; { Ссылка на элемент полинома и на предыдущий элемент }
  Begin
    Write('Введите свободный член '); { Вывод приглашения }
    ReadLn(Poly.Free); { Ввод свободного члена }
    n:=0; { Сброс счетчика степени }
    PredRef:=nil; { Установка ссылки на предыдущий элемент списка }
    while Question('Ввести слагаемое?') do { Цикл ввода полинома }
    begin
      repeat
        Write('Введите степень слагамого '); { Вывод приглашения }
        ReadLn(nNew);                { Ввод степени слагаемого }
        if nNew<=n then { Проверка корректности значения степени }
          WriteLn(#7'ОШИБКА ВВОДА!') { Вывод сообщения об ошибки }
      until nNew>n; { Выход из цикла при вводе степени большей чем предыдущая }
      n:=nNew; { Переопределение значения степени }
      New(Ref); { Создание новой переменной под слагаемое полинома }
      Ref^.Power:=n; { Определение степени полинома }
      Write('Введите множитель при x^',n:0,' '); { Вывод приглашения }
      ReadLn(Ref^.X);  { Ввод множителя }
      Write('Введите множитель при y^',n:0,' '); { Вывод приглашения }
      ReadLn(Ref^.Y);  { Ввод множителя }
      Write('Введите множитель при z^',n:0,' '); { Вывод приглашения }
      ReadLn(Ref^.Z);  { Ввод множителя }
      Ref^.Next:=PredRef;
      { Присоединение к введенному элементу созданной ранее очереди }
      PredRef:=Ref { Сохранение ссылки на очередь }
    end;
    Poly.Poly:=PredRef { Присоединение полинома к переменной }
  End;
PROCEDURE OutElement(Multiplier:real;Arg:char;Power:word;var OutFlag:boolean);
                                       { Процедура вывода элемента полинома }
  Begin
    if (Multiplier>0)and OutFlag then Write('+'); { Вывод знака "+"
              при наличии выведенных ранее элементах и положительном текущем }
    if Multiplier<>0 then { Если слагаемое не нулевое то }
    begin
      Write(Multiplier:0:0,'*',Arg,'^',Power); { Вывод слагаемого }
      OutFlag:=TRUE; { Подъем флага выведенных элементов }
    end
  End;
PROCEDURE OutputPoly(Poly:FullPoly); { Процедура вывода полинома }
  Var OutFlag:boolean; { Флаг - признак наличия выведенных элементов }
  Begin
    OutFlag:=FALSE; { Сброс флага }
    with Poly do
    begin
      while Poly<>nil do { Цикл вывода очереди }
      begin
        OutElement(Poly^.X,'X',Poly^.Power,OutFlag); { Вывод множителя X }
        OutElement(Poly^.Y,'Y',Poly^.Power,OutFlag); { Вывод множителя Y }
        OutElement(Poly^.Z,'Z',Poly^.Power,OutFlag); { Вывод множителя Z }
        Poly:=Poly^.Next { Переход к следующему элементу }
      end;
      { Вывод свободного члена: }
      if (Free>0)and OutFlag then Write('+');
      if (Free<>0)or not OutFlag then Write(Free:0:0)
    end;
    WriteLn { Вывод конца строки }
  End;
PROCEDURE PolySum(Poly1,Poly2:FullPoly;var Result:FullPoly);
                                             { Процедура сложения полиномов }
  Var Ref1,Ref2,Res,EndRes:BasePoly; { Ссылки на первый, второй,
  результирующий полиномы, ссылка на последний элемент результата }
  Begin
    Result.Free:=Poly1.Free+Poly2.Free; { Суммирование свободных членов }
    { Начальное определение ссылок: }
    Ref1:=Poly1.Poly;
    Ref2:=Poly2.Poly;
    Result.Poly:=nil;
    Res:=nil;
    while (Ref1<>nil)or(Ref2<>nil) do { Цикл перебора исходных полиномов }
    begin
      New(EndRes); { Создание нового элемента полинома }
      { Выбор определения результирующего элемента
        по наличию элементов в исходных полиномах: }
      if Ref1=nil
      then begin
             EndRes^:=Ref2^;  { определение результата }
             Ref2:=Ref2^.Next  { продвижение по списку }
           end
      else if Ref2=nil
           then begin
                  EndRes^:=Ref1^; { определение результата }
                  Ref1:=Ref1^.Next  { продвижение по списку }
                end
           else if Ref1^.Power>Ref2^.Power
                   { Выбор действия по значению степени }
                then begin
                       EndRes^:=Ref1^; { определение результата }
                       Ref1:=Ref1^.Next  { продвижение по списку }
                     end
                else if Ref1^.Power<Ref2^.Power
                     then begin
                            EndRes^:=Ref2^; { определение результата }
                            Ref2:=Ref2^.Next  { продвижение по списку }
                          end
                     else begin
                            { определение результата: }
                            EndRes^.Power:=Ref2^.Power;
                            EndRes^.X:=Ref2^.X+Ref1^.X;
                            EndRes^.Y:=Ref2^.Y+Ref1^.Y;
                            EndRes^.Z:=Ref2^.Z+Ref1^.Z;
                            with EndRes^ do
                              { Сброс обнуленного элемента: }
                              if (X=0)and(Y=0)and(Z=0) then
                              begin
                                Dispose(EndRes);
                                EndRes:=nil
                              end;
                             { продвижение по спискам: }
                            Ref1:=Ref1^.Next;
                            Ref2:=Ref2^.Next
                          end;
      if EndRes<>nil then { Если не было получено нулевой суммы, то:  }
        if Result.Poly=nil
        then begin { Формирование головы списка: }
               Result.Poly:=EndRes;
               Res:=EndRes
             end
        else begin { Добавление в конец списка: }
               Res^.Next:=EndRes;
               Res:=EndRes
             end
    end;
    if Res<>nil then Res^.Next:=nil { Оформление последней ссылки в списке }
  End;
PROCEDURE CopySubPoly(Poly1:BasePoly;var Poly2:BasePoly);
  Begin       { Процедура копирования полиномов (кроме свободного члена) }
    if Poly1<>nil
    then begin
           New(Poly2);  { Создание новой переменной }
           Poly2^:=Poly1^; { Копирование полей }
           CopySubPoly(Poly1^.Next,Poly2^.Next); { Копирование оставшейся части очереди }
         end
    else Poly2:=nil { "Копирование хвоста" }
  End;
PROCEDURE CopyPoly(Poly1:FullPoly; var Poly2:FullPoly);
  Begin                        { Процедура копирования полиномов (полного) }
    Poly2.Free:=Poly1.Free;                { Копирование свободного члена }
    CopySubPoly(Poly1.Poly,Poly2.Poly); { Копирование слагаемых с переменными }
  End;
PROCEDURE MultPolyToVar(Element:BasePoly;Poly:FullPoly;var Result:FullPoly);
                          { Умножение полинома на слагаемое (переменную) }
  Var Ref:BasePoly; { Ссылка на полином для продвижения при умножении }
  Begin
    CopyPoly(Poly,Result); { Копирование полинома }
    Ref:=Result.Poly; { Начальная установка ссылки на элемент результата }
    while Ref<>nil do { Цикл продвижения по результату }
    begin
      { Умножение элемента результата на заданное слагаемое: }
      Ref^.Power:=Ref^.Power+Element^.Power;
      Ref^.X:=Ref^.X*Element^.X;
      Ref^.Y:=Ref^.Y*Element^.Y;
      Ref^.Z:=Ref^.Z*Element^.Z;
      Ref:=Ref^.Next { Продвижение по списку }
    end
  End;
PROCEDURE MultPolyToPoly(Poly1,Poly2:FullPoly;var Result:FullPoly);
                     { Процедура умножения полиномов без свободных членов }
  Var Ref:BasePoly;  { Ссылка для продвижения по списку }
      Res,PredRes,Sum:FullPoly;
                        { Результат, предыдущий результат, сумма полиномов }
  Begin
    { Определение ссылок на полиномы: }
    Sum.Poly:=nil;
    Res.Poly:=nil;
    if (Poly1.Poly<>nil)and(Poly2.Poly<>nil) { Если полиномы не пусты }
    then begin   { то умножение полиномов }
           Ref:=Poly1.Poly; { начальное определение ссылки }
           while Ref<>nil do { цикл продвижения по списку }
           begin
             PredRes:=Res; { Сохранение ссылки на предыдущию операцию
                              умножения полинома на переменную }
             MultPolyToVar(Ref,Poly2,Res); { Умножение полинома2 на элемент полинома1 }
             PolySum(Res,PredRes,Sum); { Сложение нового результата умножения с предыдущим }
             Ref:=Ref^.Next; { Продвижение по списку }
             DisposerList(PredRes.Poly) { Уничтожение предыдущего результата }
           end;
           Result:=Sum; { Определение результата функции }
           DisposerList(Res.Poly) { Уничтожение последнего промежуточного результата }
         end
    else Result.Poly:=nil { иначе сброс результата }
  End;
PROCEDURE MultPolyToConst(Poly:FullPoly;Constant:real;var Result:FullPoly);
                        { Умножение полинома на константу (свободный член) }
  Var Ref:BasePoly; { Вспомогательная ссылка для продвижения по полиному }
  Begin
    CopyPoly(Poly,Result); { Копирование полинома }
    Ref:=Result.Poly; { Начальное определение вспомогательной ссылки }
    while Ref<>nil do { Цикл продвижения по списку }
    begin
      { Умножение переменных на свободный член: }
      Ref^.X:=Ref^.X*Constant;
      Ref^.Y:=Ref^.Y*Constant;
      Ref^.Z:=Ref^.Z*Constant;
      Ref:=Ref^.Next { Продвижение по списку }
    end
  End;
PROCEDURE MultPoly(Poly1,Poly2:FullPoly;var Result:FullPoly);
                                            { Процедура умножения полиномов }
  Var Result1,Result2,Result3,Result4:FullPoly; { Вспомогательные результаты }
  Begin
    MultPolyToPoly(Poly1,Poly2,Result1); { Умножение полиномов (без свободных членов) }
    { Умножение полиномов на свободные члены: }
    MultPolyToConst(Poly1,Poly2.Free,Result2);
    MultPolyToConst(Poly2,Poly1.Free,Result3);
    { Сложение результатов: }
    PolySum(Result1,Result2,Result4);
    PolySum(Result3,Result4,Result);
    Result.Free:=Poly1.Free*Poly2.Free; { Вычисление свободного члена }
    { Уничтожение списков: }
    DisposerList(Result1.Poly);
    DisposerList(Result2.Poly);
    DisposerList(Result3.Poly);
    DisposerList(Result4.Poly);
  End;
PROCEDURE GetPolyProto(Poly:FullPoly;var Result:FullPoly);
                                          { Процедура вычисления производной }
  Var VarFlag:'X'..'Z'; { Флаг переменной дифференцирования }
      Ref,PredRef:BasePoly; { Ссылки на полином }
  Begin
    Write('Введите переменную дифференцирования '); { Вывод приглашения }
    VarFlag:=UpCase(ReadKey); { Чтение ответа }
    WriteLn(VarFlag); { Вывод ответа }
    CopyPoly(Poly,Result); { Копирование полиномов }
    Ref:=Result.Poly; { Начальное определение ссылки }
    while Ref<>nil do { Цикл продвижения по списку }
    begin
      with Ref^ do
      begin
        case VarFlag of { Выбор по флагу переменной }
          'X':begin
                { Интегрирование по X: }
                X:=X*Power;
                Y:=0;
                Z:=0
              end;
          'Y':begin
                { Интегрирование по Y: }
                X:=0;
                Y:=Y*Power;
                Z:=0
              end;
          'Z':begin
                { Интегрирование по Z: }
                X:=0;
                Y:=0;
                Z:=Z*Power
              end
        end;
        Dec(Power) { Пересчет степени }
      end;
      PredRef:=Ref; { Сохранение предыдущей ссылки }
      Ref:=Ref^.Next { Продвижение по списку }
    end;
    if Result.Poly<>nil { Если полином не пуст }
    then if PredRef^.Power=0 { то, если последний элемент имеет нулевую степень }
         then begin { то - переопределение свободного члена: }
                case VarFlag of
                  'X':Result.Free:=PredRef^.X;
                  'Y':Result.Free:=PredRef^.Y;
                  'Z':Result.Free:=PredRef^.Z
                end;
                Ref:=Result.Poly; { Переход на начало списка }
                while Ref^.Next<>PredRef do Ref:=Ref^.Next;
                { Продвижение до предпоследнего элемента}
                Dispose(Ref^.Next); { Уничтожение последнего элемента }
                Ref^.Next:=nil { Оформление конца списка }
              end
         else Result.Free:=0 { иначе - обнуление свободного члена }
    else Result.Free:=0 { иначе - обнуление свободного члена }
  End;
VAR Poly1,Poly2,PolyResult:FullPoly; { Полиномы }
BEGIN
  ClrScr; { Очистка экрана }
  { Вывод запроса действия: }
  WriteLn('Введите действие: (1) - сложение полиномов ');
  WriteLn('                  (2) - умножение полиномов ');
  WriteLn('                  (3) - вычисление производной полинома ');
  case ReadKey of { Чтение ответа }
    '1':begin
          WriteLn('СЛОЖЕНИЕ');
          WriteLn('ВВОД ПЕРВОГО ПОЛИНОМА'); { Вывод подсказки }
          InputPoly(Poly1); { Ввод полинома }
          WriteLn('ВВОД ВТОРОГО ПОЛИНОМА'); { Вывод подсказки }
          InputPoly(Poly2); { Ввод полинома }
          Write('Poly1=');
          OutputPoly(Poly1); { Вывод полинома }
          Write('Poly2=');
          OutputPoly(Poly2); { Вывод полинома }
          PolySum(Poly1,Poly2,PolyResult);  { Сложение полиномов }
          Write('PolySum=');
          OutputPoly(PolyResult); { Вывод полинома }
          { Уничтожение списков: }
          DisposerList(Poly1.Poly);
          DisposerList(Poly2.Poly);
          DisposerList(PolyResult.Poly);
        end;
    '2':begin
          WriteLn('УМНОЖЕНИЕ');
          WriteLn('ВВОД ПЕРВОГО ПОЛИНОМА'); { Вывод подсказки }
          InputPoly(Poly1); { Ввод полинома }
          WriteLn('ВВОД ВТОРОГО ПОЛИНОМА'); { Вывод подсказки }
          InputPoly(Poly2); { Ввод полинома }
          Write('Poly1=');
          OutputPoly(Poly1); { Вывод полинома }
          Write('Poly2=');
          OutputPoly(Poly2); { Вывод полинома }
          MultPoly(Poly1,Poly2,PolyResult);
          Write('PolyProduct=');
          OutputPoly(PolyResult); { Вывод полинома }
          { Уничтожение списков: }
          DisposerList(Poly1.Poly);
          DisposerList(Poly2.Poly);
          DisposerList(PolyResult.Poly);
        end;
    '3':begin
          WriteLn('ДИФФЕРЕНЦИРОВАНИЕ');
          WriteLn('ВВОД ПОЛИНОМА'); { Вывод подсказки }
          InputPoly(Poly1); { Ввод полинома }
          Write('Poly=');
          OutputPoly(Poly1); { Вывод полинома }
          GetPolyProto(Poly1,PolyResult);
          Write('(Poly)''=');
          OutputPoly(PolyResult); { Вывод полинома }
          { Уничтожение списков: }
          DisposerList(Poly1.Poly);
          DisposerList(PolyResult.Poly);
        end
  end;
END.

Бесплатные примеры программ
Примеры написанных программ
Помощь студентам по программированию