基于MATLAB整数系数多项式提取系数

基于正则的整数系数多项式提取系数,只需输入多项式字符串和字符串对应的选项,注意系数是整数,自变量须为‘a’

效果如下:

%  自变量用'a表示'

%  如果多项式是数字则choice=1

regexp_poly_example('1',1)

ans =

     1

regexp_poly_example('1000',1)

ans =

        1000

%  多项式最大阶数是1阶choice=2

%  如果在choice=2的选择里面(只有一阶的式子)出现了choice=1就显示出错

regexp_poly_example('a+1',1)

你的输入出现了错误

ans =

   NaN

regexp_poly_example('a+1',2)

ans =

     1     1

regexp_poly_example('2*a+1',2)

ans =

     2     1

regexp_poly_example('-a',2)

ans =

    -1     0

regexp_poly_example('-a-1',2)

ans =

    -1    -1

regexp_poly_example('a',2)

ans =

     1     0

regexp_poly_example('5*a',2)

ans =

     5     0

regexp_poly_example('5*a+4',2)

ans =

     5     4

% choice=3,即出现了^的标准,意味着多项式有23阶的

regexp_poly_example('a^2',3)

ans =

     1     0     0

regexp_poly_example('a^2-a',3)

ans =

     1    -1     0

regexp_poly_example('a^2-a+1',3)

ans =

     1    -1     1

regexp_poly_example('4*a^5+a^2-a+1',3)

ans =

     4     0     0     1    -1     1

regexp_poly_example('-a^10-4*a^5+a^2',3)

ans =

    -1     0     0     0     0    -4     0     0     1     0     0

regexp_poly_example('-a^12+11*a^6+a^3-a^2-a+1',3)

ans =

    -1     0     0     0     0     0    11     0     0     1    -1    -1     1

regexp_poly_example('-a^12+11*a^6+5*a^3-16*a^2-a+1',3)

ans =

    -1     0     0     0     0     0    11     0     0     5   -16    -1     1

regexp_poly_example('-a^12+11*a^6+a^3-a^2-a+1',3)

ans =

    -1     0     0     0     0     0    11     0     0     1    -1    -1     1

regexp_poly_example('-12*a^13+12*a^10+5*a^6+11*a^4-16*a^2-a+1',3)

ans =

   -12     0     0    12     0     0     0     5     0    11     0   -16    -1     1

regexp_poly_example('12*a^13+12*a^10+5*a^6+11*a^4-16*a^2-a+1',3)

ans =

    12     0     0    12     0     0     0     5     0    11     0   -16    -1     1

regexp_poly_example('a^13+12*a^10+5*a^6+11*a^4-16*a^2-a+1',3)

ans =

     1     0     0    12     0     0     0     5     0    11     0   -16    -1     1

代码如下:

function y=regexp_poly_example(x,choice)

%  copyright by fantuanxiaot

%  关注 fantuanxiaot 的量化学习博客:<a href="http://blog.sina.com.cn/u/2029278253" target="_blank">http://blog.sina.com.cn/u/2029278253</a>

%  为了提取符号表达式中的系数向量

%  输入的字符串以 a 为自变量

%  x 是输入的字符串 %  字符串的系数必须是整数

%  输入的字符串诸如: 5*a^3-10*a+2, -a^3-100*a, a^5-10*a^4+a^3-100

%  输入的诸如 '1','2','100','-1000'(无字母一类:choice=1)

%  '100*a-4','100*a','a','a-1','-5*a','-a-2'(无阶数一类即只有一阶而没有二阶:choice=2)

%  5*a^3-10*a+2, -a^3-100*a, a^5-10*a^4+a^3-100(为有阶数的一类)

clc

format compact

y=false;

if choice~=1 && choice~=2 && choice~=3

    disp('你的输入出现了错误')

    return;

end

if ~ischar(x)

    disp('你的输入出现了错误')

    return;

end

%  无字母一类

if choice==1

    y=str2double(x);

    %  如果输入了其他的 '-5*a','5*a^3-10*a+2' 类型则出错了显示 NaN

    if isnan(y)

        disp('你的输入出现了错误')

    end

    return;

end

%  无阶数一类

if choice==2

    exp='[+-]?\d*';

    %  得到了系数

    xishu=regexp(x,exp,'match');

    if (length(xishu))==2 || ((length(xishu))==1 && isnan(str2double(xishu{1})))

        %  如果系数出现了 '-' 形式则处理

        if isnan(str2double(xishu{1}))

            xishu{1}=strcat(xishu{1},'1');

        end

        y=str2double(xishu);

        %  针对 '-a' 的情况

        if length(y)==1

            y=[y 0];

        end

        return;

    end

    %  则出现了 'a-1','a+10','a-100' 之类且不是 '-a','-2*a' 的情况的情况

    %  如果 (length(xishu))==1

    %  出现的情况如 'a+2','-2*a','a-100','2*a' 之类的情况

    exp1='^[-]?\d*';  %  判断开头

    exp2='[+-]?\d*$';  %  判断结尾

    match1=regexp(x,exp1,'match');

    match2=regexp(x,exp2,'match');

    if (length(xishu))==1 && ~isempty(match1)

        y=[str2double(xishu) 0];

        return;

    end

    if (length(xishu))==1 && ~isempty(match2)

        y=[1 str2double(xishu)];

        return;

    end

    %  如果出现了 'a' 这种情行

    if (length(xishu))==0

        y=[1 0];

        return;

    end  

end

%  其他类别

if choice==3

    %  先对幂后面的阶数进行提取

    exp_1='(?<=a\^)\d*(?=[+-]?)';

    %  得到了阶数

    %  获取到了阶数的数字 char

    jieshu=regexp(x,exp_1,'match');

    %  如果是空集则输入错误

    if isempty(jieshu)

        disp('你的输入出现了错误')

        return;

    end

    %  获取系数, 仅仅适用于对应阶乘的系数, 如果 x='a^3-2*a^2', 那么开始的系数 1 就要加上去

    %  并没有获取得到诸如 'a^3-2*a^2+a-1','a^3-2*a^2+2*a' 的一阶和零阶的系数

    exp_2='[+-]?\d*?(?=\*?a\^)';

    xishu=regexp(x,exp_2,'match');

    %  如果系数只有 '-','+' 之类的符号而没有数字则处理

    for i=1:length(xishu)

        if length(xishu{i})==1 && isnan(str2double(xishu{i}))

            xishu{i}=strcat(xishu{i},'1');

        end

    end   

    %  如果 x='a^3-2*a^2', 那么开始的系数 1 就要加上去

    if length(jieshu)~=length(xishu)

        xishu1{1}='1';

        xishu1=[xishu1 xishu];

        xishu=xishu1;

    end

    %  现在对末尾的字符进行提取

    %  如 'a^3-2*a^2+a-1' 提取 'a-1'

    %  'a^3-2*a^2+2*a' 提取 '2*a'

    exp_3='(?<=\^\d+)[\w*\*+-]+$';

    resid=regexp(x,exp_3,'match');

    %  则后面没有了拖尾巴

    xishu=str2double(xishu);

    y=zeros(1,str2double(jieshu{1})-1);

    for i=1:length(jieshu)

        y(str2double(jieshu{1})+1-str2double(jieshu{i}))=xishu(i);

    end

    if isempty(resid)

        y=[y 0 0];

        return;

    end

    %  进一步提取和简化

    str=resid{1};

    %  存在以下几种情况:

    %  '+1','-1','-a-1','+a-1','-a','+a','-2*a','+2*a'

    %  先提取系数

    exp_4='[+-]?\d*';

    xishu_resid=regexp(str,exp_4,'match');

    if length(xishu_resid)==2

        %  如果系数只有 '-','+' 之类的符号而没有数字则处理

        for j=1:2

            if isnan(str2double(xishu_resid{j}))

                xishu_resid{j}=strcat(xishu_resid{j},'1');

            end

        end

        pa=str2double(xishu_resid);

        y=[y pa];

        return;

    end

    %  如果 length(xishu_resid)==1

    %  则有以下情况 '+2*a','-a','+1','-1'

    exp_5='[+-]\d*(?=\*?a$)';

    exp_6='[+-]\d*$';

    match1=regexp(str,exp_5,'match');

    match2=regexp(str,exp_6,'match');

    if ~isempty(match1)

        if isnan(str2double(match1))

            match1{1}=strcat(match1{1},'1');

        end

        y=[y str2double(match1{1}) 0];

        return;

    end

    if ~isempty(match2)

        if isnan(str2double(match2))

            match2{1}=strcat(match2{1},'1');

        end

        y=[y 0 str2double(match2{1})];

        return;

    end

end