一、 问题描述
创建一个能够进行四则运算的多项式类,要求:
1、 用升幂排列的系数数组表示多项式,p(x)=a0+a1x +a2x2+a3x3表示为p=[a0,a1,a2,a3];
2、 重载四个运算符+、-、*和\。以及定义积分和微分计算
二、 求解思路
对于一个多项式,其最关键的参数为系数和对应自变量的次方,若将多项式的系数按顺序排列,则自动的顺序将代表自变量的次方(规定最右的系数为常数项,从左向右依次递增),则对于多项式的操作完全变为对多项式系数的操作,多项式的加法变为对应系数的相加,多项式的减法变为对应系数的相减,多项式的乘法变为对应系数的卷积,多项式的除法变为对应系数的去卷积,多项式的积分变为将每个系数除以1加上所在自变量次数,并增添一个常数项(默认为1),多项式的微分变为将每个系数乘上所在所在自变量次数。
对于升幂排列,首先需要改变函数Docpolynom,将输出的数组利用fliplr函数反向,然后在已有的降幂排列的char函数基础上,首先在char函数内需要先将输入的系数矩阵利用fliplr函数反向排列,然后在char函数的循环中,将次方的初值设置为0,然后递增。
对于多项式的加法,需要先求出两者的最高项数的差,将项数低的一个多项式系数数组的高次由0填充(放置于原有数组后),然后将两个多项式系数数组相加
对于多项式的减法,与前文的加法做同样处理后,只需将两个多项式系数数组相减即可完成。
对于多项式的乘法,首先定义一个全为0,长度为输入的两数组长度减1的列向量(new),然后利用循环,对于列向量的每一位,将输入两数组的位次(j,k)之和-1等于列向量位数(i)的系数之积(aiaj)相加 (aiaj)既是所需要的列向量的值。
对于多项式的除法,首先需要将输入的数组利用fliplr反向,然后记录下两者的最高项数s1,s2,如果s1<s2,则输出结果为0,否则所得到的结果系数数组为一个长度为(s1-s2+1)的列向量,开始循环,利用find函数,此函数返回数组中所有不为0的位置,定义m为第一个不为0的位置,如果m不大于0,则说明已经结束,退出循环,然后判断系数长度是否小于被除的系数长度,如果小于,则退出循环,如果循环继续,则将被除项的最高次系数除以除项的最高次系数,得到new(i),然后将原有系数组减去(new(i)原有系数组),得到新除后的余数,进行下一次的循环,直到退出或结束循环
对于多项式的积分,定义新的常数项为1,则将其他的项数的系数除以所在项数次数加一则得到新的项数的系数。
对于多项式的微分,将定义一个比微分前的项数少一的列向量,新的列向量的第i位的系数为原多项式第i+1位系数所在的项数次数
三、 程序代码
classdef DocPolynom
% file: @DocPolynom/DocPolynom.m, define a polynomial class
% Public properties
%四则运算,导数,积分
properties
coef = []; % double vector of polynomial coefficients [highest order ... lowest order]
end
% Class methods
methods
function obj = DocPolynom(c)
% Construct a DocPolynom object using the coefficients supplied
if isa(c,'DocPolynom')
obj.coef = c.coef;
else
obj.coef = c(:).'; % c(:) is always a column vector, no matter whether c is an array or matrix.
end %把c变成一个列向量
obj.coef=fliplr(obj.coef);
end % DocPolynom
function c = double(obj)
c=double(obj.coef);
end % double
function s = char(obj)
% Created a formated display of the polynom
% as powers of x
obj.coef=fliplr(obj.coef);
if all(obj.coef == 0)
s = '0';
else
d = 0; %修改d的初值
s = [];
for a = obj.coef;
if a ~= 0;
if ~isempty(s)
if a > 0
s = [s ' + '];
else
s = [s ' - '];
a = -a;
end
end
if a ~= 1 || d == 0
s = [s num2str(a)];
if d > 0
s = [s '*'];
end
end
if d >= 2
s = [s 'x^' int2str(d)];
elseif d == 1
s = [s 'x'];
end
end
d = d+1; %d递增
end
end
end % char
function disp(obj)
% DISPLAY
disp([' ' char(obj)])
end % disp
function b = subsref(a,s)
% SUBSREF Implement obj([1 ...]), a special subscripted assignment
switch s.type
case '()'
ind = s.subs{:};
for k = 1:length(ind)
b(k) = eval(strrep(char(a),'x',num2str(ind(k))));
end
case '.'
switch s.subs
case 'coef'
b = a.coef;
otherwise
error(['''' s.subs '''' ' is not a DocPolynom property'])
end
otherwise
error('Specify value for x as obj(x)')
end
end % subsref
function r = plus(obj1,obj2)
% PLUS Implement obj1 + obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
r = DocPolynom([obj1.coef zeros(1,k) ] + [obj2.coef zeros(1,-k)]);
end % plus
function r = mtimes(obj1,obj2)
% MTIMES Implement obj1 * obj2 for DocPolynoms.
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
s1=length(obj1.coef);
s2=length(obj2.coef);
new=zeros(s1+s2-1,1);
% r = DocPolynom(conv(obj1.coef,obj2.coef)); %conv返回卷积
for i=1:s1+s2-1
for j=1:s1
for k=1:s2
if (j+k-1)==i
new(i)=new(i)+obj1.coef(j)*obj2.coef(k);
end
end
end
end
r=DocPolynom(new);
end % mtimes
function r = minus(obj1,obj2)
% PLUS Implement obj1 - obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
r = DocPolynom([obj1.coef zeros(1,k)] - [obj2.coef zeros(1,-k)]);
end % minus
function r = mrdivide(obj1,obj2)
% MRDIVIDE Implement obj1 / obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj1.coef=fliplr(obj1.coef);
obj2 = DocPolynom(obj2);
obj2.coef=fliplr(obj2.coef);
s1=length(obj1.coef);
s2=length(obj2.coef);
if s1<s2
new=0;
else
new=zeros(s1-s2+1,1);
for i=1:s1-s2+1
index=find(obj1.coef);
if length(index)>0
m=index(1);
else
break;
end
if s1-m+1<s2
break;
end
new(i)=obj1.coef(m)/obj2.coef(1);
rs=zeros(1,s1);
for k=m:m+s2-1
rs(k)=obj2.coef(k-m+1);
end
obj1.coef=obj1.coef-new(i)*rs;
end
end
newnew=fliplr(new');
r=DocPolynom(newnew);
% r = DocPolynom(fliplr(deconv(obj1.coef,obj2.coef))); %conv返回去卷积
end % mrdivide
function r=int(obj1)
%integral
obj1 = DocPolynom(obj1);
n=length(obj1.coef);
new_n=ones(n+1,1);
for i=2:n+1
new_n(i)=obj1.coef(i-1)/(i-1);
end
r=DocPolynom(new_n);
end
function r=diff(obj1)
%differential
obj1 = DocPolynom(obj1);
n=length(obj1.coef);
new_n=zeros(n-1,1);
for i=2:n
new_n(i)=obj1.coef(i)*(i-1);
end
r=DocPolynom(new_n);
end
function y = polyval(obj,x)
% POLYVAL POLYVAL(obj,x) evaluates obj at the points x.
y = 0;
for a = obj.coef
y = y.*x + a;
end
end % polyval
end % methods
end % classdef
clear;
clc;
p1=DocPolynom([1,2,3]);
disp('第一个多项式:')
disp(p1)
p2=DocPolynom([0,1,2,3]);
disp('第二个多项式:')
disp(p2)
disp('多项式的和:');
disp(p1+p2)
disp('多项式的差:');
disp(p1-p2)
disp('多项式的商:');
disp(p2/p1)
disp('多项式的积:');
disp(p1*p2)
disp('多项式积分:');
p1=int(p1);
disp(p1)
disp('多项式微分:');
p1=diff(p1);
disp(p1)
四、 实验结果
如图,输入[1,2,3]输出1+2x+3x2,输入[0,1,2,3],输出x+2*x2+3*x^3,两者的和以及差如图所示,二式除以一式的结果如图,,对第一个多项式积分,输出结果如图,对积分后的 式子微分,结果如图所示
五、 实验心得
- 对于新的概念注意学习已有的模板
- 对于复杂的事物必须抓住事物的关键,由浅入深
- 类操作是面向对象的编程,一个类中首先定义变量,随后定义各类方法,定义一个类后,可以用定义的各种方法直接操作变量,在某些情况下,能够大大的提高效率。