Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Многочлены

Автор: Рустам 22.12.2009 3:16

Даны числа a0 a1 a2 a3 a4 a5
Составить многочлен шестой степени (x-a0)(x-a1)(x-a2)(x-a3)(x-a4)(x-a5)

Добавлено через 1 мин.
думал много над ней.. передо мной была сложность одна.. .когда раскрываешь скобки образуются всевозможные комбинации с двумя а потом с тремя , четырьми... для комбинаций с двумя а придумал...а когда идут 3 , 4.. че то додуматься не могу... помогите пожалуйста

Автор: sheka 22.12.2009 3:24

Тебе надо математическое решение?

Автор: Рустам 22.12.2009 9:20

cам точно не уверен думаю в ответе должно быть так... x6+число*х5... и так далее

Автор: volvo 22.12.2009 14:07

Напиши 2 процедуры: умножения и сложения многочленов ( в качестве начального примера можно взять вот это: http://forum.pascal.net.ru/index.php?s=&showtopic=14845&view=findpost&p=86016 ), и перемножай в цикле многочлены...

Автор: Lapp 22.12.2009 14:58

Нужно сделать:
- тип для представления многочлена (как массива);
- процедуру для умножения;
- ну и для вывода.

Вот, примерно так:

const
n=6;
e=1e-7;

type
tPoly= array[0..n]of double;

procedure Product(p,q: tPoly; var r: tPoly);
var
i,j: integer;
begin
for i:=0 to n do r[i]:=0;
for i:=0 to n do for j:=0 to n-i do r[i+j]:=r[i+j]+p[i]*q[j]
end;

procedure Show(p: tPoly);
var
i: integer;
begin
for i:=0 to n do
if Abs(p[i])>e then begin
if p[i]<0 then Write('-') else if i>0 then Write('+');
if Abs(Abs(p[i])-1)>e then Write(Abs(p[i]):4 :2);
if i>0 then Write('x');
if i>1 then Write('^',i)
end
end;

const
a: tPoly= (2,-1,0,0,0,0,0); {2-x}
b: tPoly= (2,1,0,0,0,0,0); {2+x}

var
c: tPoly;
i: integer;

begin
Product(a,b,c);
Show( c );
ReadLn
end.

Тут для примера производится умножение (2-х)(2+х). Запусти и убедись, что оно равно 4-х2 smile.gif.
А для твоей задачи лучше всего создать массив из специально заполненных полиномов. Примерно такой:
const
a: array[1..6]of tPoly= (
(0,1,<-a1>,0,0,0),
(0,1,<-a2>,0,0,0),
(0,1,<-a3>,0,0,0),
(0,1,<-a4>,0,0,0),
(0,1,<-a5>,0,0,0),
(0,1,<-a6>,0,0,0)
);

Либо, если числа заранее неизвестны, то запрашивай их в цикле и ставь на нужные места.
Если что неясно - спрашивай.

Добавлено через 1 мин.
Извиняюсь, volvo, форму ответа давно загрузил..

Добавлено через 1 мин.
Цитата(volvo @ 22.12.2009 10:07) *
Напиши 2 процедуры: умножения и сложения многочленов
Сложение в данном случае не нужно )).

Автор: Lapp 22.12.2009 16:30

Не удержался - сделал вывод поизящнее:

const
n=6;
e=1e-7;

type
tPoly= array[0..n]of double;

procedure Product(p,q: tPoly; var r: tPoly);
var
i,j: integer;
begin
for i:=0 to n do r[i]:=0;
for i:=0 to n do for j:=0 to n-i do r[i+j]:=r[i+j]+p[i]*q[j]
end;

function Show(p: tPoly): string;
var
i: integer;
s,t: string;
begin
s:='';
for i:=0 to n do
if Abs(p[i])>e then begin
if p[i]<0 then s:=s+'-' else if i>0 then s:=s+'+';
if Abs(Abs(p[i])-1)>e then begin
Str(Abs(p[i]):4 :2,t);
s:=s+t
end;
if i>0 then s:=s+'x';
if i>1 then begin
Str(i,t);
s:=s+'^'+t
end
end;
Show:=s
end;

const
a: tPoly= (2,-1,0,0,0,0,0); {2-x}
b: tPoly= (2,1,0,0,0,0,0); {2+x}

var
c: tPoly;
i: integer;

begin
Product(a,b,c);
WriteLn('('+Show(a)+')'+'('+Show(b)+')='+Show©);
ReadLn
end.

smile.gif

Автор: volvo 22.12.2009 16:35

Цитата
Сложение в данном случае не нужно )).
В "данном" - это в каком? Естественно, если ты объединил умножение и сложение, тебе сложение отдельно не надо. Я предпочитаю, чтоб мои процедуры выполняли строго определенную задачу: сложение - это сложение, умножение - это умножение. Принцип "Разделяй и властвуй" в действии...

Автор: Рустам 22.12.2009 17:56

Извини Lapp немного застрял с организацией цикла



const
{a: tPoly= (3,1,0,0,0,0,0); {2-x}
{b: tPoly= (3,1,0,0,0,0,0); {2+x}

a: array [1..6] of tPoly=
(
(2,1,0,0,0,0,0),
(1,1,0,0,0,0,0),
(3,1,0,0,0,0,0),
(4,1,0,0,0,0,0),
(5,1,0,0,0,0,0),
(1,1,0,0,0,0,0)
);


var
c: tPoly;
i: integer;

begin
clrscr;
for i:=1 to 6 do
begin
Product(c,a[i],c);
WriteLn('('+Show(a)+')'+'('+Show(b)+')='+Show©);
end;

ReadLn
end.



скажи правильно ли я делаю. чтобы перемножить 6 множителей надо каждый множитель умножать на результат
Product(c,a[i],c); но для начала надо присвоить с как бы единицу то есть c:=(1,0,0,0,0,0,0) но такой вариант че то паскалю не нравится?

Автор: Lapp 22.12.2009 18:49

Цитата(Рустам @ 22.12.2009 13:56) *
чтобы перемножить 6 множителей надо каждый множитель умножать на результат
Product(c,a[i],c); но для начала надо присвоить с как бы единицу то есть c:=(1,0,0,0,0,0,0) но такой вариант че то паскалю не нравится?
Все вроде правильно. Что именно ему не нравится? Скажи, что за ошибка.


Добавлено через 2 мин.
только ты понял, что в первые элементы нужно заносить не "ai", а "-ai" ?

Добавлено через 10 мин.
Я заметил некоторые недочеты (и даже одну ошибку sad.gif ) в выводе.. Кроме этого, я перевернул вывод - теперь старший член идет первым (как обычно). Вот исправленный вариант полностью:
const
n=6;
e=1e-7;

type
tPoly= array[0..n]of double;

procedure Product(p,q: tPoly; var r: tPoly);
var
i,j: integer;
begin
for i:=0 to n do r[i]:=0;
for i:=0 to n do for j:=0 to n-i do r[i+j]:=r[i+j]+p[i]*q[j]
end;

function Show(p: tPoly): string;
var
i: integer;
s,t: string;
f: boolean;
begin
s:='';
f:=true;
for i:=n downto 0 do
if Abs(p[i])>e then begin
if p[i]<0 then s:=s+'-' else if (i<n)and not f then s:=s+'+';
if (i=0)or(Abs(Abs(p[i])-1)>e) then begin
Str(Abs(p[i]): 8: 2,t);
while t[1]=' ' do Delete(t,1,1);
while t[Length(t)]='0' do Delete(t,Length(t),1);
if t[Length(t)]='.' then Delete(t,Length(t),1);
s:=s+t
end;
if i>0 then s:=s+'x';
if i>1 then begin
Str(i,t);
s:=s+'^'+t
end;
f:=false
end;
Show:=s
end;

const
c: tPoly=(1,0,0,0,0,0,0);
a: array [1..6] of tPoly=(
(-2,1,0,0,0,0,0),
(-1,1,0,0,0,0,0),
(-3,1,0,0,0,0,0),
(-4,1,0,0,0,0,0),
(-5,1,0,0,0,0,0),
(-1,1,0,0,0,0,0)
);

var
i: integer;

begin
for i:=1 to 6 do begin
Product(c,a[i],c);
Write('('+Show(a[i])+')')
end;
WriteLn(' = '+Show©);
ReadLn
end.


(и еще одно исправление в Show.. Надеюсь, теперь все Ок))

Автор: Рустам 22.12.2009 19:48

да я понял, просто пробовал различные варианты,разбирался так скажем..а код мне в принципе ясен и сама идея)) сейчас посмотрю ещё разик)

Добавлено через 11 мин.
Спасибо Большое за проделанную работу!!! Но единственное не совсем понятна эта работа со строками. Будьте добры объясните пожалуйста


for i:=n downto 0 do
if Abs(p[i])>e then begin
if p[i]<0 then s:=s+'-' else if (i<n)and not f then s:=s+'+';
if (i=0)or(Abs(Abs(p[i])-1)>e) then begin
Str(Abs(p[i]): 8: 2,t);
while t[1]=' ' do Delete(t,1,1);
while t[Length(t)]='0' do Delete(t,Length(t),1);
if t[Length(t)]='.' then Delete(t,Length(t),1);
s:=s+t
end;



Автор: Lapp 23.12.2009 9:12

Цитата(Рустам @ 22.12.2009 15:48) *
Спасибо Большое за проделанную работу!!! Но единственное не совсем понятна эта работа со строками. Будьте добры объясните пожалуйста

Вообще-то, это не совсем относится к самой задаче. Если тебе неясно или не нравится, ты можешь выводить так, как считаешь нужным. Но объяснить тоже нетрудно ))..

Собственно, почти все сложности проистекают из-за того, что ты не сказал, какие значения могут принимать ai - любые или только целые. С целыми все было бы гораздо проще. Но я сделал для действительных, причем если дробная часть равна нулю - она не выводится (как обычно люди пишут). Так что при сдаче можешь блестнуть выводом дробных значений smile.gif (только проверь сначала как следует).


// весь вывод осуществляем в строку s
for i:=n downto 0 do // выводим в обратном порядке, от больших степеней к маленьким
// нулевые члены не выводим; проверка на ноль для действительных чисел делается сравнением с маленьким числом
if Abs(p[i])>e then begin
// знак выводим отдельно
// если это самый первый член (признак f, от first), и он положительный, то знак + опускаем
// (у меня сейчас возникло подозрение, что условие i<n - лишнее. Проверь)
if p[i]<0 then s:=s+'-' else if (i<n)and not f then s:=s+'+';
// знак вывели, дальше работаем только с модулем.
if (i=0)or(Abs(Abs(p[i])-1)>e) then begin // единицу при степени х не выводим (кроме нулевой степени)
Str(Abs(p[i]): 8: 2,t); // переводим коэффициент в строку t
while t[1]=' ' do Delete(t,1,1); // если t имеет пробелы в начале - удаляем
while t[Length(t)]='0' do Delete(t,Length(t),1); // удаляем завершающие незначащие нули (после точки)
if t[Length(t)]='.' then Delete(t,Length(t),1); // если в конце стоит точка - удаляем
s:=s+t // дописываем значение к знаку
end;
// дальше идет вывод х (везде, кроме нулевой степени)
// потом вывод показателя степени (начиная со второй)
// и сброс признака f в false


Вот, вроде, и вся наука )).

Автор: Рустам 25.12.2009 2:05

спасибо вам большое! правда ваше сообщение увидел тока щас , но программу сдал... немного импровизации и юмора помогло... Вообщем спасибо за труды , хорошие вы люди. буду почаще здесь бывать... помощь вам надеюсь не будет лишней

Автор: Lapp 25.12.2009 2:13

Цитата(Рустам @ 24.12.2009 22:05) *
спасибо за труды , хорошие вы люди. буду почаще здесь бывать... помощь вам надеюсь не будет лишней
Приятно помочь в добром деле )).
Конечно, заходи - всегда рады!


Добавлено через 6 мин.
Цитата(volvo @ 22.12.2009 12:35) *
В "данном" - это в каком? Естественно, если ты объединил умножение и сложение, тебе сложение отдельно не надо. Я предпочитаю, чтоб мои процедуры выполняли строго определенную задачу: сложение - это сложение, умножение - это умножение. Принцип "Разделяй и властвуй" в действии...
Извиняюсь, только сейчас увидел этот пост.
Ты имеешь в виду реализацию умножения столбиком? В принципе я согласен, конечно, но тут действительно просто рука не поднялась разводить всю кухню, когда все помещается в один цикл.. ))