[从头学数学] 第137节 分式 小结与复习题

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了筑基中期的修炼,
这次要修炼的目标是[分式 小结与复习题]。

正剧开始:

星历2016年03月17日 11:46:50, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[分式 小结与复习题]。



<span style="font-size:18px;">		var s = [
			'2s(s-2t)/(s+2t)',
			'1/(x^[2]-y^[2])',
			'2',
			'(u^[2]-4uv+4v^[2]-2)/(u^[2]-4v^[2])',
			'x^[-6]y^[-9]',
			'9x^[2]/(y^[6]z^[2])'
			
		
		
		];</span>



小伟想看一看这些分式有没有什么规律,于是随意画了几张图:


<span style="font-size:18px;">		//2(1)
		var result = 0;
		var array = [];
		var tmp = [];
		var colorArray = ['red', 'orange', '#0088FF', 'green', 'cyan', 'blue', '#FF00FF',
			'#888888', 'black'];
			
		var count = 0;
		for (var s = -10; s < 10; s+=2) {
			array = [];
			for (var t = -10; t < 10; t+=2) {
				result = (s-2*t)/(3*s)*(6*Math.pow(s, 2)/(s+2*t));
				
				array.push(shape.point3D(s, result/20, t));
			}
			tmp = [].concat(array);
			shape.multiLineDraw(tmp, colorArray[count%8], r);
			tmp = [].concat(array);
			shape.pointDraw(tmp, colorArray[count%8], r);
			count++;</span>



<span style="font-size:18px;">		//2(2)
		var result = 0;
		var array = [];
		var tmp = [];
		var colorArray = ['red', 'orange', '#0088FF', 'green', 'cyan', 'blue', '#FF00FF',
			'#888888', 'black'];
			
		var count = 0;
		for (var z = -10; z < 10; z+=2) {
			array = [];
			for (var x = -10; x < 10; x+=2) {
				//x-->x z-->y
				result = (x-z)/(x+z)+Math.pow(x-z, 2);
				
				array.push(shape.point3D(x, result/10-5, z));
			}
			tmp = [].concat(array);
			shape.multiLineDraw(tmp, colorArray[count%8], r);
			tmp = [].concat(array);
			shape.pointDraw(tmp, colorArray[count%8], r);
			count++;
			
				
				
		}</span>


<span style="font-size:18px;">		//2(4)
		var result = 0;
		var array = [];
		var tmp = [];
		var colorArray = ['red', 'orange', '#0088FF', 'green', 'cyan', 'blue', '#FF00FF',
			'#888888', 'black'];
			
		var count = 0;
		var u , v;
		for (var z = -10; z < 10; z+=2) {
			array = [];
			for (var x = -10; x < 10; x+=2) {
				//x-->u z-->v
				u = x;
				v = z;
				result = (u-2*v)/(u+2*v)-2/(u*u-4*v*v);
				
				array.push(shape.point3D(x, result, z));
			}
			tmp = [].concat(array);
			shape.multiLineDraw(tmp, colorArray[count%8], r);
			tmp = [].concat(array);
			shape.pointDraw(tmp, colorArray[count%8], r);
			count++;
			
				
				
		}</span>

这图可够乱的,小伟完全瞧不出什么规律来,算了,不管它了。



<span style="font-size:18px;">		var s = [
			'6',
			'b^[-1]',
			'(2x^[2]-12x+16)/(x^[2]-16)',
			'1/16p^[2]q^[3]r^[-1]+1/(2q)',
			'x/(1+x^[2])',
			'1/(a-b)',
			'-b/(a+b)',
			'(x+y)/(x-y)']</span>


小伟为了做这些非常烦的题,专门又给以前的多项式添加了一个计算两个多项式相乘的工具:

<span style="font-size:18px;">###
# @usage   两个多项式相乘
# @author  mw
# @date    2016年03月17日  星期四  14:47:14 
# @param   限制很多,但对于项数比较多的一层括号,可省不少麻烦
# @return
#
###
#多项式s1与s2的乘积,s1, s2都不能有括号
#它们的单项之间用+号或-号相连
#例如a+2b2c3, 2a+4b-c3-1等
#代数字母与次数之间不要有其它符号,不要有乘号和除号
def polymul(s1, s2):
    if (s1 == '' or s2 == ''):
        return;
    
    #只能有+或-号连接各项,不能有括号,分数要先化成小数
    s = s1.replace('-', '+-');
    if (s[0] == '+'):
        s = s[1:];
    #各项
    terms_1 = s.split('+');

    s = s2.replace('-', '+-');
    if (s[0] == '+'):
        s = s[1:];
    #各项
    terms_2 = s.split('+');
    
    len1 = len(terms_1);
    len2 = len(terms_2);

    resultStr = '';

    for i in range(len1):
        for j in range(len2):
            resultStr += monomul(terms_1[i], terms_2[j])+'+';

    lens = len(resultStr);
    if (resultStr[lens-1] == '+'):
        resultStr = resultStr[:lens-1];

    return resultStr;

def monomul(s1, s2):
    a1 = monoDecomposite(s1);
    a2 = monoDecomposite(s2);

    coeff = eval('('+a1[0]+')'+'*'+'('+a2[0]+')');
    return str(coeff)+a1[1]+a2[1];
    

#分解出单项式的系数和其余部分 
def monoDecomposite(s):
    if (s == ''):
        return ['0', ''];

    if (s[0].isalpha()):
        return ['1', s];

    lens = len(s);
    if (s[0] == '-'):       
        if (s[1].isalpha()):
            return ['-1', s[1:]];
        else:
            index = 1;
            while (index <= lens-1 and (not s[index].isalpha())):
                index+=1;
            return [s[:index], s[index:]];
    else:
        index = 0;
        while (index <= lens-1 and (not s[index].isalpha())):
            index+=1;
        return [s[:index], s[index:]];</span>

加上以前做的:

<span style="font-size:18px;">###
# @usage   单项式相关概念
# @author  mw
# @date    2016年02月26日  星期五  10:00:14 
# @param
# @return
#
###
#单项式
#可以有**, ^号,暂时只能处理代号为一个字母的式子,像x_1, x_n, ...这种还不能处理。
def monomial(s):
    #原始复本
    s0 = s;
    
    s = s.replace('**', '^');
    s = s.replace('*', '');

    if (s.find('+') != -1 or (s.find('-') != -1 and s.find('-')!=0)):
        print(s0, '不是单项式。');
        return [];
        
    try:
        #系数
        sign = 1;
        if s[0] == '-':
            #负号
            sign = -1;
            s = s[1:];
        coefficient = 1;

        #字符串长度
        length = len(s);
        index = 0;
        while (not s[index].isalpha()):
            index+=1;
            if index >= length:
                index = length;
                break;

        if (index > 0):
            coefficient = float(s[:index]);
            if abs(int(coefficient)-coefficient) < 0.001:
                coefficient = int(coefficient);        
            s = s[index:];
            
        coefficient = sign * coefficient;
        #系数为0的项,其实就是0
        if (coefficient == 0):
            return [];
        #print(coefficient, s);

        length = len(s);
        array = [];
        result = [];
        if (length > 0):
            index = 0;
            index2 = 0;
            name = '';
            degree = 0;
            while index < length:        
                if s[index].isalpha():
                    if (name != ''):
                        array.append([name, degree]);
                        name = '';
                        degree = 0;
                    name = s[index];
                    degree = 1;
                    index += 1;
                else:
                    index2 = index;
                    tmp = '';
                    while (not s[index2].isalpha()):
                        index2+=1;
                        if (index2 >= length):
                            index2 = length;
                            break;
                    tmp = s[index:index2];
                    tmp = tmp.replace('^', '');
                    degree = float(tmp);
                    if abs(int(degree)-degree) < 0.001:
                        degree = int(degree);

                    index = index2;
            if (name != ''):
                array.append([name, degree]);
                name = '';
                degree = 0;
                
            #print(array);

            #所有字母,去除重复的
            setA = set();
            size = len(array);
            #单项式的次数
            totalDegree = 0;
            for i in range(size):
                setA.add(array[i][0]);
                totalDegree += array[i][1];

            listA = list(setA);
            listA.sort();
            size2 = len(listA);
            result = [];
            for i in range(size2):
                #计算每个字母的次数(degree)
                tmp = 0;
                for j in range(size):
                    if listA[i] == array[j][0]:
                        tmp += array[j][1];

                result.append([listA[i], tmp]);

            print('单项式{0} 的系数是{1}, 次数是{2},详细是{3}。'.format(\
                s0, coefficient, totalDegree, result));
        else:
            totalDegree = 0;
            if (coefficient != 0):
                print('单项式{0} 的系数是{1}, 次数是{2},'.format(\
                    s0, coefficient, 0));
            else:
                print('这个数是0, 暂无规定。');
        #返回单项式的次数
        return [coefficient, totalDegree, result];
    except:
        print(s0, '有误,无法正确计算。');

###
# @usage   多项式相关概念
# @author  mw
# @date    2016年02月26日  星期五  10:30:37 
# @param   如果有括号,需要先自行去除,
# @return
#
###
def polynomial(s):
    if (s == ''):
        return;
    
    #预留复本
    s0 = s;

    #只能有+或-号连接各项,不能有括号,分数要先化成小数
    s = s.replace('-', '+-');
    if (s[0] == '+'):
        s = s[1:];
    #各项
    terms = s.split('+');
    

    print('多项式{0} 具有以下的项: {1}\n其中各单项分别是:'.format(s0, terms));

    try:
        size = len(terms);
        array = [];
        for i in range(size):
            #此处也可扩展单项的合法性检查。
            if (terms[i] == ''):
                pass;
            else:
                tmp = monomial(terms[i]);
                #对于返回[]的项,剔除掉
                if len(tmp)>0:
                    array.append(tmp);
        #print(array);

        size2 = len(array);

        for i in range(size2):
            #判断系数是否是0
            if array[i][0] == 0:
                continue;
            for j in range(i+1, size2):
                if array[j][0] == 0:
                    continue;
                else:
                    if (sameTerm(array[i], array[j])):
                        #合并同类项
                        array[i][0]+=array[j][0];
                        array[j][0] = 0;

        result = [];
        for i in range(size2):
            #判断系数是否是0
            if array[i][0] == 0:
                continue;
            else:
                #保留三位小数
                array[i][0] = round(array[i][0], 6);
                result.append(array[i]);

        print('合并同类项后详细情况是:', result);
        sResult = '';
        size3 = len(result);
        if (size3)>0:
            for i in range(size3):
                tmp1 = result[i][0];
                if (tmp1 >= 0):
                    if (tmp1 != 1):
                        sResult += '+'+str(tmp1);
                    else:
                        sResult += '+';
                if (tmp1 < 0):
                    if (tmp1!=-1):
                        sResult += str(tmp1);
                    else:
                        sResult += '-';

                tmp2 = result[i][2];
                length = len(tmp2);
                if (length == 0 and abs(tmp1)==1):
                    sResult += '1';
                else:
                    for j in range(length):
                        if tmp2[j][1] != 1:
                            sResult += tmp2[j][0]+str(tmp2[j][1]);
                        else:
                            sResult += tmp2[j][0];
            if sResult[0] == '+':
                sResult = sResult[1:];
        else:
            #所有项的系数刚好抵消,导致结果为0
            sResult = '0';
        print('合并同类项后是 => {0}\n\n'.format(sResult));
    except:
        print(s0, '有误,无法进行多项式操作。');
    return;

                

#同类项判断
def sameTerm(a, b):
    #由于a, b具有以下格式[1, 1, [['v', 1]]] [系数, 次数, 详细元素]
    if (a[1] == 0 and b[1] == 0):
        return True;
    
    if (a[1] != b[1]):
        #次数不同
        return False;
    if (len(a[2]) != len(b[2])):
        #元素个数不同
        return False;

    a1 = list(a[2]);
    b1 = list(b[2]);
    a1 = sorted(a1, key=lambda num:num[0]);
    b1 = sorted(b1, key=lambda num:num[0]);
    size = len(a1);
    for i in range(size):
        if a1[i][0] != b1[i][0] or a1[i][1] != b1[i][1]:
            return False;

    return True;

###
# @usage   代数式,可以对系数中含计算式的情况进行计算,得出简化后的多项式字符串
# @author  mw
# @date    2016年02月27日  星期六  09:23:44 
# @param
# @return
#
###
#代数式
def algExpr(s):
    s0 = s;

    #判断字符串中左右括号是否匹配
    if s.count('(') - s.count(')') != 0:
        print(s, '左右括号数目不匹配,表达式有误。');
        return '';
    #去除空格
    s = s.replace(' ', '');
    #存放需要计算的表达式子串
    sub = '';
    length = len(s);
    #新字符串
    sNew = '';
    #括号层次
    bracket = 0;

    result = [];

    #需要计算的部分,是从每一个单项的开始处,一般只需要计算系数
    need = 1;
    #精度
    precision = 6;
    
    #遍历字符串s
    i = 0;
    while i < length:
        if (s[i] == '('):
            bracket+=1;
            sub += s[i];
        elif (s[i] == ')'):
            bracket -=1;
            sub += s[i];                
        elif (s[i].isalpha()):
            if sub != '':
                if (sub[-1]=='*'):
                    sub=sub[:-1];
                sNew += str(round(eval(sub), precision))+ s[i];
                sub = '';
            else:
                sNew += s[i];
            #由于字母后面是次数,不需要计算
            #need = 0;            
        elif (s[i] == '+' or s[i] == '-'):
            if (bracket == 0):
                if sub != '':
                    if (sub[-1]=='*'):
                        sub=sub[:-1];
                    sNew += str(round(eval(sub), precision))+ s[i];
                    sub = '';
                else:
                    sNew += s[i];
                #need = 1;
            else:
                sub += s[i];
        else:
            if (need == 1):
                sub += s[i];
            else:
                sNew += s[i];

        i += 1;

    if sub != '':
        if (sub[-1]=='*'):
            sub=sub[:-1];
        sNew += str(round(eval(sub), precision));
        sub = '';

    #print(sNew);
    return sNew;</span>

这么多,反而越来越难以解答[人叫板老师]的题了,难道非要阿伟长出两只手来拿个草稿本慢慢算?


<span style="font-size:18px;">if __name__ == '__main__':
    s1 = polymul('5x+2', 'x+1');
    s2 = polymul('-3', 'x2+x');
    s = algExpr(s1+'+'+s2);
    print(polynomial(s));


多项式5xx+5x+2x+2+-3x2+-3x 具有以下的项: ['5xx', '5x', '2x', '2', '', '-3x2', '', '-3x']
其中各单项分别是:
单项式5xx 的系数是5, 次数是2,详细是[['x', 2]]。
单项式5x 的系数是5, 次数是1,详细是[['x', 1]]。
单项式2x 的系数是2, 次数是1,详细是[['x', 1]]。
单项式2 的系数是2, 次数是0,
单项式-3x2 的系数是-3, 次数是2,详细是[['x', 2]]。
单项式-3x 的系数是-3, 次数是1,详细是[['x', 1]]。
合并同类项后详细情况是: [[2, 2, [['x', 2]]], [4, 1, [['x', 1]]], [2, 0, []]]
合并同类项后是 => 2x2+4x+2

=> x = -1</span>

x = -1时分母为0了,所以这个方程无解!


<span style="font-size:18px;">if __name__ == '__main__':
    s1 = polymul('2x', '2x+5');
    s2 = polymul('-2', '2x-5');
    s3 = polymul('-2x+5', '2x+5');
    s = algExpr(s1+'+'+s2+'+'+s3);
    print(polynomial(s));

>>> 
多项式4xx+10x+-4x+10+-4xx+-10x+10x+25 具有以下的项: ['4xx', '10x', '', '-4x', '10', '', '-4xx', '', '-10x', '10x', '25']
其中各单项分别是:
单项式4xx 的系数是4, 次数是2,详细是[['x', 2]]。
单项式10x 的系数是10, 次数是1,详细是[['x', 1]]。
单项式-4x 的系数是-4, 次数是1,详细是[['x', 1]]。
单项式10 的系数是10, 次数是0,
单项式-4xx 的系数是-4, 次数是2,详细是[['x', 2]]。
单项式-10x 的系数是-10, 次数是1,详细是[['x', 1]]。
单项式10x 的系数是10, 次数是1,详细是[['x', 1]]。
单项式25 的系数是25, 次数是0,
合并同类项后详细情况是: [[6, 1, [['x', 1]]], [35, 0, []]]
合并同类项后是 => 6x+35


None
>>> 2*(-35/6)/(2*(-35/6)-5)-2/(2*(-35/6)+5)
1.0
</span>

验算通过,这个解是x = -35/6



好吧,这些烦琐的分式计算,还是留给需要计算它们的小朋友吧。


小伟在这里总结一下工具的使用:

<span style="font-size:18px;">if __name__ == '__main__':
    #可计算多项式的乘法,但不能有括号
    s1 = polymul('x+y+z+u+v', 'x+y+z-u-v');
    print(polynomial(s1));

    #指数上有负号时会出错,这个可以解决,但是会要求更复杂的写法
    s2 = '(5*2*3-8-6)a(-2)a2'
    print(polynomial(algExpr(s2)));

    #对于正指数会很方便
    s3 = '(5*2*3-8-6)a2abcdef2g+s(2*3)d3-28.66gdf-3';
    print(polynomial(algExpr(s3)));


</span>

<span style="font-size:18px;">>>> 
多项式1xx+1xy+1xz+-1xu+-1xv+1yx+1yy+1yz+-1yu+-1yv+1zx+1zy+1zz+-1zu+-1zv+1ux+1uy+1uz+-1uu+-1uv+1vx+1vy+1vz+-1vu+-1vv 具有以下的项: ['1xx', '1xy', '1xz', '', '-1xu', '', '-1xv', '1yx', '1yy', '1yz', '', '-1yu', '', '-1yv', '1zx', '1zy', '1zz', '', '-1zu', '', '-1zv', '1ux', '1uy', '1uz', '', '-1uu', '', '-1uv', '1vx', '1vy', '1vz', '', '-1vu', '', '-1vv']
其中各单项分别是:
单项式1xx 的系数是1, 次数是2,详细是[['x', 2]]。
单项式1xy 的系数是1, 次数是2,详细是[['x', 1], ['y', 1]]。
单项式1xz 的系数是1, 次数是2,详细是[['x', 1], ['z', 1]]。
单项式-1xu 的系数是-1, 次数是2,详细是[['u', 1], ['x', 1]]。
单项式-1xv 的系数是-1, 次数是2,详细是[['v', 1], ['x', 1]]。
单项式1yx 的系数是1, 次数是2,详细是[['x', 1], ['y', 1]]。
单项式1yy 的系数是1, 次数是2,详细是[['y', 2]]。
单项式1yz 的系数是1, 次数是2,详细是[['y', 1], ['z', 1]]。
单项式-1yu 的系数是-1, 次数是2,详细是[['u', 1], ['y', 1]]。
单项式-1yv 的系数是-1, 次数是2,详细是[['v', 1], ['y', 1]]。
单项式1zx 的系数是1, 次数是2,详细是[['x', 1], ['z', 1]]。
单项式1zy 的系数是1, 次数是2,详细是[['y', 1], ['z', 1]]。
单项式1zz 的系数是1, 次数是2,详细是[['z', 2]]。
单项式-1zu 的系数是-1, 次数是2,详细是[['u', 1], ['z', 1]]。
单项式-1zv 的系数是-1, 次数是2,详细是[['v', 1], ['z', 1]]。
单项式1ux 的系数是1, 次数是2,详细是[['u', 1], ['x', 1]]。
单项式1uy 的系数是1, 次数是2,详细是[['u', 1], ['y', 1]]。
单项式1uz 的系数是1, 次数是2,详细是[['u', 1], ['z', 1]]。
单项式-1uu 的系数是-1, 次数是2,详细是[['u', 2]]。
单项式-1uv 的系数是-1, 次数是2,详细是[['u', 1], ['v', 1]]。
单项式1vx 的系数是1, 次数是2,详细是[['v', 1], ['x', 1]]。
单项式1vy 的系数是1, 次数是2,详细是[['v', 1], ['y', 1]]。
单项式1vz 的系数是1, 次数是2,详细是[['v', 1], ['z', 1]]。
单项式-1vu 的系数是-1, 次数是2,详细是[['u', 1], ['v', 1]]。
单项式-1vv 的系数是-1, 次数是2,详细是[['v', 2]]。
合并同类项后详细情况是: [[1, 2, [['x', 2]]], [2, 2, [['x', 1], ['y', 1]]], [2, 2, [['x', 1], ['z', 1]]], [1, 2, [['y', 2]]], [2, 2, [['y', 1], ['z', 1]]], [1, 2, [['z', 2]]], [-1, 2, [['u', 2]]], [-2, 2, [['u', 1], ['v', 1]]], [-1, 2, [['v', 2]]]]
合并同类项后是 => x2+2xy+2xz+y2+2yz+z2-u2-2uv-v2


None
多项式16a-2a2 具有以下的项: ['16a', '-2a2']
其中各单项分别是:
单项式16a 的系数是16, 次数是1,详细是[['a', 1]]。
单项式-2a2 的系数是-2, 次数是2,详细是[['a', 2]]。
合并同类项后详细情况是: [[16, 1, [['a', 1]]], [-2, 2, [['a', 2]]]]
合并同类项后是 => 16a-2a2


None
多项式16a2abcdef2g+s6d3-28.66gdf-3 具有以下的项: ['16a2abcdef2g', 's6d3', '-28.66gdf', '-3']
其中各单项分别是:
单项式16a2abcdef2g 的系数是16, 次数是10,详细是[['a', 3], ['b', 1], ['c', 1], ['d', 1], ['e', 1], ['f', 2], ['g', 1]]。
单项式s6d3 的系数是1, 次数是9,详细是[['d', 3], ['s', 6]]。
单项式-28.66gdf 的系数是-28.66, 次数是3,详细是[['d', 1], ['f', 1], ['g', 1]]。
单项式-3 的系数是-3, 次数是0,
合并同类项后详细情况是: [[16, 10, [['a', 3], ['b', 1], ['c', 1], ['d', 1], ['e', 1], ['f', 2], ['g', 1]]], [1, 9, [['d', 3], ['s', 6]]], [-28.66, 3, [['d', 1], ['f', 1], ['g', 1]]], [-3, 0, []]]
合并同类项后是 => 16a3bcdef2g+d3s6-28.66dfg-3


None
>>> </span>

反正是烦琐透了。还不如用草稿本划同类项来得快呢。


本节到此结束,欲知后事如何,请看下回分解。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值