Программа
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.
Бесплатные примеры программ
Примеры написанных программ
Помощь студентам по программированию