[从头学数学] 第210节 带着计算机去高考(二)

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼。设想一个场景:
如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗
?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉。

正剧开始:


星历2016年05月17日 16:48:27, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起做着2001年的江苏省数学高考题]。


[从头学数学] 第210节 带着计算机去高考(二)_第1张图片




[从头学数学] 第210节 带着计算机去高考(二)_第2张图片


<span style="font-size:18px;">#题1
>>> 
1 1
1 3

def tmp1():
    #定特例
    angle = math.pi/4;

    for i in range(1,2):
        for n in range(4):
            angle_1 = angle+math.pi/2*n
            sini = math.sin(i*angle_1);
            cos = math.cos(angle_1);
            if (sini*cos > 0):
                print(i, n+1);</span>


[从头学数学] 第210节 带着计算机去高考(二)_第3张图片


<span style="font-size:18px;">#题2
def tmp2():
    '''
    s1 = '(x-1)^[2]+(y+1)^[2]-(x+1)^[2]-(y-1)^[2] = 0';
    s2 = 'y = (2-x)';

    val1 = ['x', '-1'];
    val2 = ['y', '1'];
    val3 = ['x', '1'];
    val4 = ['y', '-1'];
    
    a = strpow_n(val1, 2)+strpow_n(val2, 2)+minus(strpow_n(val3, 2))+minus(strpow_n(val4, 2));
    a = strcombine(a);
    print(a); #['(0)', '(-4)*x', '(0)', '(0)', '(4)*y']

    #-4x+8-4x=0
    '''

    #两条直线的交点
    A = [1, -1];
    B = [-1, 1];

    C = [0, 2];
    D = [1, 1];
    
    cross = geo.crossPointOfTwoLine([A, B], [C, D]);
    #print(cross); #平行 
    
    #AB距离
    d1 = geo.distance2D(A, B); #2.8284271247461903

    #两平行线的距离
    d = geo.lineDistance2D([A, B], [C, D]);
    print(d); #1.414213562373095

    #半经
    R = ((d1/2)**2+d**2)**0.5;
    print('R = ', R);

    #求AB的中垂线方程
    line = geo.perpendicular([A, B]);
    print(line); #[[0.0, 0.0], [10.0, 10.0]]

    #求中垂线与圆心所在直线的交点
    cross = geo.crossPointOfTwoLine([line[0], line[1]], [C, D]);
    print(cross); #[1.0, 1.0]

    #这是一个R=2, 圆心(1, 1)的方程</span>




<span style="font-size:18px;">#题3
def tmp3():
    #4*(4-d)*(4+d) = 48</span>


[从头学数学] 第210节 带着计算机去高考(二)_第4张图片


[从头学数学] 第210节 带着计算机去高考(二)_第5张图片



<span style="font-size:18px;">//题5
	if (1) {      
        var r = 20;            
        config.setSector(1,1,1,1);              
        config.graphPaper2D(0, 0, r);            
        config.axis2D(0, 0,180);              
                
        //坐标轴设定        
        var scaleX = 2*r, scaleY = 2*r;          
        var spaceX = 0.5, spaceY = 0.5;           
        var xS = -10, xE = 10;          
        var yS = -10, yE = 10;          
        config.axisSpacing(xS, xE, spaceX, scaleX, 'X');            
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');            
                    
        var transform = new Transform();            
        //存放函数图像上的点        
        var a = [], b = [], c = [], d = [];          
                  
        //需要显示的函数说明    
                    //希腊字母表(存此用于Ctrl C/V  
            //ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ  
            //αβγδεζηθικλμνξοπρστυφχψω  
        var f1 = 'ρ = 2sin(θ+pi/4)', f2 = '', f3 = '', f4 = '';        
            
  
        //函数描点    
        //参数方程  
        var x, y;  
        var pointA = [];  
          
        for (var thita = 0; thita < Math.PI*2; thita +=Math.PI/24) {  
            pointA = [2*Math.sin(thita+Math.PI/4), thita];  
            a.push(polar2XY(pointA));  
        }  
          
                  
        //存放临时数组        
        var tmp = [];        
                  
        //显示变换        
        if (a.length > 0) {        
            a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);         
            //函数1        
            tmp = [].concat(a);            
            shape.pointDraw(tmp, 'red');            
            tmp = [].concat(a);            
            shape.multiLineDraw(tmp, 'pink');          
                      
            plot.setFillStyle('red');        
            plot.fillText(f1, 100, -180, 200);          
        }  
  
          
    }</span>




<span style="font-size:18px;">#题6
>>> math.acos(0);
1.5707963267948966
>>> math.acos(1);
0.0
>>> math.acos(-1);
3.141592653589793</span>






<span style="font-size:18px;">#题8
>>> 
A

def tmp8():
    a = math.pi/8;
    b = math.pi/6;

    cond1 = math.sin(a)+ math.cos(a);
    cond2 = math.sin(b) + math.cos(b);

    a = cond1;
    b = cond2;

    if (a<b):
        print('A');

    if (a > b):
        print('B');

    if (a*b < 1):
        print('C');

    if (a*b > 2):
        print('D');
    </span>


[从头学数学] 第210节 带着计算机去高考(二)_第6张图片


[从头学数学] 第210节 带着计算机去高考(二)_第7张图片


[从头学数学] 第210节 带着计算机去高考(二)_第8张图片


<span style="font-size:18px;">//题9
	if (1) {  
      
        var r = 20;      
        config.setSector(1,1,1,1);        
        config.graphPaper2D(0, 0, r);      
        config.axis2D(0, 0, 180);    
          
        var scale = 3*r;  
      

        var triangle = new Triangle();  
        var transform = new Transform();  
        var array = triangle.solve([3.464, 2.45, 2.45,  '?', '?', '?']);  
          
        shape.angleDraw(transform.translate(array, -200/scale, 0), 'red', scale, ['B', 'D', 'C\'']);    
        //shape.areaDraw(array, 'red', scale);   
  
        //document.write(array+'<br/>');  
  
    }</span>


[从头学数学] 第210节 带着计算机去高考(二)_第9张图片


[从头学数学] 第210节 带着计算机去高考(二)_第10张图片


<span style="font-size:18px;">#题11
def tmp11():
    S_1 = a*b/math.cos(thita);
    S_2 = a*b/math.cos(thita);
    S_3 = 0.5*b*b/math.cos(thita) + (a+a-b/2)*b/math.cos(thita);
    #相等</span>


[从头学数学] 第210节 带着计算机去高考(二)_第11张图片


[从头学数学] 第210节 带着计算机去高考(二)_第12张图片






<span style="font-size:18px;">#题14
def tmp14():
    c = 5;
    #[(9+(9/16)*y^[2])^[0.5], y], [-5, 0], [5, 0]
    #y^[2]+25 = x^[2];
    #x^[2] =9+(9/16)y^[2]

    #a1 - a2 = 6;
    #a1^[2] + a2^[2] = 100;
    t1 = strpow_n(['6', 'a_2'], 2);
    t2 = strmono('a_[1]^[2]');

    t1 = strcombine(t1);
    print(t1);    
	
	
		if (1) {
		var equation = new Equation();  
          
        var a = [2, 12, 36-100] 
        equation.quadratic(a);  
	}
	
>>> 3.4*9.4/10
3.196
</span>



<span style="font-size:18px;">#题15
def tmp15():
    #(1-q^[n+1])*2 = (1-q^[n])+(1-q^[n+2] Q[1, -2, 1]
		if (1) {
		var equation = new Equation();  
          
        var a = [1, -2, 1] 
        equation.quadratic(a);  
	}

方程 1x^[2] + -2x + 1 = 0 =>
Δ = b^[2] - 4ac = 0 ;
方程的解为:x1 = x2 = 1 ;
方程根与系数的关系:x1 + x2 = 2, x1 * x2 = 1 ;</span>



有2n个点,每个点作为直角顶点,另一个点可以在半圆里除它以外再找一个。


[从头学数学] 第210节 带着计算机去高考(二)_第13张图片


<span style="font-size:18px;">#题17
def tmp17():
    SA = AB = BC = 1;
    AD = 1/2;

    V_S_ABCD = (AD+BC)*AB/2*SA/3;

    print('V= ', V_S_ABCD);

    #平面ABCD中CD上的高DE
    CD = (AD**2+AB**2)**0.5;
    DE = CD/AB*AD;
    #AE
    AE = AD/CD*DE;

    SD = (SA**2+AD**2)**0.5;
    SE = (SA**2+AE**2)**0.5;

    print('DE = ', DE);
    print('SD = ', SD);
    print('SE = ', SE);
    print('AE = ', AE);

    #F点为AB和CD的延长线交点,G为D作的SF的垂线
    SF = (SA**2+AB**2)**0.5;
    DG = SD*CD/SF;
    AG = SA*AB/SF;

    print('SF = ', SF);
    print('DG = ', DG);
    print('AG = ', AG);</span>

<span style="font-size:18px;">>>> 
V=  0.25
DE =  0.5590169943749475
SD =  1.118033988749895
SE =  1.0307764064044151
AE =  0.25
SF =  1.4142135623730951
DG =  0.8838834764831845
AG =  0.7071067811865475

>>> math.atan(0.707);
0.6154085176292563
>>> 180*_/math.pi
35.2603107365587

        var array = triangle.solve([0.884, 0.707, 0.5, '?', '?', '?']);  
          
        shape.angleDraw(transform.translate(array, -200/scale, 0), 'red', scale, ['A', 'D', 'G']); 
		</span>


<span style="font-size:18px;">	if (1) {  
      
        var r = 20;      
        config.setSector(1,1,1,1);        
        config.graphPaper2D(0, 0, r);      
        config.axis2D(0, 0, 180);    
          
        var scale = 8*r;  
      

        var triangle = new Triangle();  
        var transform = new Transform();  
        var array = triangle.solve([0.559, 1.118, 1.030, '?', '?', '?']);  
          
        shape.angleDraw(transform.translate(array, -200/scale, 0), 'red', scale, ['S', 'E', 'D']);    
        //shape.areaDraw(array, 'red', scale);   
  
        //document.write(array+'<br/>');  
  
    }</span>


[从头学数学] 第210节 带着计算机去高考(二)_第14张图片





<span style="font-size:18px;">#题18
def tmp18():
    
    z = complex(0, 1)*pow(complex(1, -1), 3);
    print(z);

    real = z.real;
    print(real);
    image = z.imag;

    print(180/math.pi*math.atan(image/real));
	
>>> 
(2-2j)
2.0
-0.7853981633974483

(2-2j)
2.0
-45.0
>>> (2+0.707)*1.414
3.8276979999999994</span>


[从头学数学] 第210节 带着计算机去高考(二)_第15张图片




[从头学数学] 第210节 带着计算机去高考(二)_第16张图片





贴一下用到的工具,一部分是代数式的,一部分是几何的,以防遗漏

<span style="font-size:18px;">###
# @usage   代数式字符串的运算
# @author  mw
# @date    2016年05月17日  星期二  16:48:56 
# @param
# @return
#
###

#计算代数式用, 传入的是单项式,返回coef*expr的形式
def strmono(s):
    #'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'
    stmp = s;
    size = len(stmp);
    alphaIndex = 0;
    signIndex = 0;
    
    for i in range(size):
        if (stmp[i].isalpha()):
            alphaIndex = i;
            break;
        if (i >= size-1):
            alphaIndex = i+1;

    if (stmp[0] == '-'):
        signIndex = 1;
        if (signIndex >= alphaIndex):
            return '(-1)*'+stmp[alphaIndex:];
        else:
            if alphaIndex >= size:
                return '(-'+stmp[signIndex:alphaIndex]+')';
            return '(-'+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:];
    else:
        signIndex = 0;        
        if (signIndex >= alphaIndex):
            return '(1)*'+stmp[alphaIndex:];
        else:
            if alphaIndex >= size:
                return '('+stmp[signIndex:alphaIndex]+')';
            return '('+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:];

#计算两个单项式的乘积
def strmul(mono1, mono2):
    #这个处理是保证每个单项式统一格式(coef)*expr
    '''
    stmp1 = strmono(s1);
    stmp2 = strmono(s2);
    '''

    if (mono1[0] != '(' or mono2[0] != '('):
        #如果没有规格化,那么就做一下
        mono1 = strmono(mono1);
        mono2 = strmono(mono2);
    else:
        stmp1 = mono1;
        stmp2 = mono2;

    #乘号的位置
    signIndex1 = stmp1.find('*');
    signIndex2 = stmp2.find('*');
    if (signIndex1 == -1):
        coef1 = stmp1;
        expr1 = '';
    else:
        coef1 = stmp1[:signIndex1];
        expr1 = stmp1[signIndex1+1:];

    if (signIndex2 == -1):
        coef2 = stmp2;
        expr2 = '';
    else:
        coef2 = stmp2[:signIndex2];
        expr2 = stmp2[signIndex2+1:];
        
    coef = coef1+'*'+coef2;
    
    if (signIndex1 == -1 or signIndex2 == -1):
        expr = expr1+expr2;
    else:
        expr = expr1+'*'+expr2;

    if (expr == ''):
        return '('+str(round(eval(coef), 6))+')';
    return '('+str(round(eval(coef), 6))+')*'+expr;
    
#计算两个单项式的商
def strdiv(s1, s2):
    #这个处理是保证每个单项式统一格式(coef)*expr
    stmp1 = strmono(s1);
    stmp2 = strmono(s2);

    #乘号的位置
    signIndex1 = stmp1.find('*');
    signIndex2 = stmp2.find('*');
    if (signIndex1 == -1):
        coef1 = stmp1;
        expr1 = '';
    else:
        coef1 = stmp1[:signIndex1];
        expr1 = stmp1[signIndex1+1:];

    if (signIndex2 == -1):
        coef2 = stmp2;
        expr2 = '';
    else:
        coef2 = stmp2[:signIndex2];
        expr2 = stmp2[signIndex2+1:];
        
    coef = coef1+'/'+coef2;
    
    if (signIndex1 == -1 and signIndex2 != -1):
        expr = '('+expr2+')^[-1]';
    elif (signIndex1 == -1 or signIndex2 == -1):
        expr = expr1+expr2;
    else:
        expr = expr1+'/'+expr2;

    if (expr == ''):
        return '('+str(round(eval(coef), 6))+')';
    return '('+str(round(eval(coef), 6))+')*'+expr;


#找一个字符串中所有待查找子串的位置,返回位置阵列
def findall(string, sub):
    size = len(string);
    index = [];

    cur = string.find(sub);
    index.append(cur)
    
    while (index[-1] != -1):        
        cur = string.find(sub, index[-1]+1);
        index.append(cur);   

    return index;

#计算单项式的乘方, s^n
def strpow(s, n):
    stmp = strmono(s);
    signIndex = stmp.find('*');
    if (signIndex == -1):
        coef = stmp+'**'+str(n);
        expr = '';
        return '('+str(round(eval(coef), 6))+')';
    else:
        coef = stmp[:signIndex]+'**'+str(n);
        expr = '('+stmp[signIndex+1:]+')^['+str(n)+']';

    return '('+str(round(eval(coef), 6))+')*'+expr;

#计算代数式用,传入的两个阵列都具有['s1', 's2', ..., 'sn']这样的格式
def strdot(array1, array2):
    size1 = len(array1);
    size2 = len(array2);
    result = [];
    
    for i in range(size1):
        for j in range(size2):
            result.append(strmul(array1[i], array2[j]));

    return result;


#把格式化后的单项式分解成[coef, expr]对组的形式
def explodemono(mono):
    stmp = mono;

    #乘号的位置
    signIndex = stmp.find('*');
    if (signIndex == -1):
        coef = stmp;
        expr = '';
    else:
        coef = stmp[:signIndex];
        expr = stmp[signIndex+1:];

    return [coef, expr];

#合并同类项,传入的阵列具有['s1', 's2', ..., 'sn']这样的格式
def strcombine(array):
    size = len(array);
    explode = [];
    for i in range(size):
        #这里传入的阵列已经是规格化后的了,否则要加一层strmono处理。
        explode.append(explodemono(array[i]));

    result = [];

    for i in range(size):
        size_1 = len(result);

        if size_1 <= 0:
            result.append(explode[i]);
        else:
            for j in range(size_1):
                if result[j][1] == explode[i][1]:
                    result[j][0] = result[j][0] + '+' + explode[i][0];
                    break;

                if j >= size_1-1:
                    result.append(explode[i]);

    result_1 = [];

    size_1 = len(result);
    for j in range(size_1):
        result[j][0] = str(round(eval(result[j][0]), 6));

        if (result[j][0] == '0'):
            result_1.append('(0)');
        else:
            tmps = result[j][1];
            if (tmps == ''):
                result_1.append('('+result[j][0]+')');
            else:            
                result_1.append('('+result[j][0]+')*'+result[j][1]);

    return result_1;

#指数为正整数的乘方
def strpow_n(array, n):
    #进行格式化处理
    s = [];

    for i in range(len(array)):
        s.append(strmono(array[i]));

    array = s;

    #计算
    result = [];

    if (n == 1):
        result = array;
    elif (n == 2):
        result = strdot(array, array);

    elif (n == 3):
        tmp = strdot(array, array);
        result = strdot(tmp, array);

    return result;

#阵列取负
def minus(array):
    for i in range(len(array)):
        if array[i][1] == '-':
            #array[i][0]是'(, 这是规范
            array[i] = array[i][0]+array[i][2:];
        else:
            array[i] = array[i][0]+'-'+array[i][1:];

    return array;
</span>


用例:

<span style="font-size:18px;">>>> 
(-3)
(3)
(1)*x
(-1)*x
(2)*x
(-2)*x
(-2)*x^[2]
(3)*x_[2]^[3]
(-3)*x_[2]^[3]

				
#计算代数式用, 传入的是单项式,返回coef*expr的形式
def strmono(s):
    #'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'
    stmp = s;
    size = len(stmp);
    alphaIndex = 0;
    signIndex = 0;
    
    for i in range(size):
        if (stmp[i].isalpha()):
            alphaIndex = i;
            break;
        if (i >= size-1):
            alphaIndex = i+1;

    if (stmp[0] == '-'):
        signIndex = 1;
        if (signIndex >= alphaIndex):
            return '(-1)*'+stmp[alphaIndex:];
        else:
            if alphaIndex >= size:
                return '(-'+stmp[signIndex:alphaIndex]+')';
            return '(-'+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:];
    else:
        signIndex = 0;        
        if (signIndex >= alphaIndex):
            return '(1)*'+stmp[alphaIndex:];
        else:
            if alphaIndex >= size:
                return '('+stmp[signIndex:alphaIndex]+')';
            return '('+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:];
                

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)):
        print(strmono(s[i]));
		
>>> 
(-9)
(3)*x
(-1)*x*x
(-2)*x*x
(-4)*x*x
(4)*x*x^[2]
(-6)*x^[2]*x_[2]^[3]
(-9)*x_[2]^[3]*x_[2]^[3]

#计算两个单项式的乘积
def strmul(s1, s2):
    #这个处理是保证每个单项式统一格式(coef)*expr
    stmp1 = strmono(s1);
    stmp2 = strmono(s2);

    #乘号的位置
    signIndex1 = stmp1.find('*');
    signIndex2 = stmp2.find('*');
    if (signIndex1 == -1):
        coef1 = stmp1;
        expr1 = '';
    else:
        coef1 = stmp1[:signIndex1];
        expr1 = stmp1[signIndex1+1:];

    if (signIndex2 == -1):
        coef2 = stmp2;
        expr2 = '';
    else:
        coef2 = stmp2[:signIndex2];
        expr2 = stmp2[signIndex2+1:];
        
    coef = coef1+'*'+coef2;
    
    if (signIndex1 == -1 or signIndex2 == -1):
        expr = expr1+expr2;
    else:
        expr = expr1+'*'+expr2;

    if (expr == ''):
        return '('+str(round(eval(coef), 6))+')';
    return '('+str(round(eval(coef), 6))+')*'+expr;
                

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)-1):
        print(strmul(s[i], s[i+1]));
		
		

>>> 
(-1.0)
(3.0)*(x)^[-1]
(-1.0)*x/x
(-0.5)*x/x
(-1.0)*x/x
(1.0)*x/x^[2]
(-0.666667)*x^[2]/x_[2]^[3]
(-1.0)*x_[2]^[3]/x_[2]^[3]
(-1.0)*x_[2]^[3]/x_[2]^[3]
(-1.5)*x_[2]^[3]/x^[2]
(1.0)*x^[2]/x
(-1.0)*x/x
(-2.0)*x/x
(-1.0)*x/x
(0.333333)*x
(-1.0)

#计算两个单项式的商
def strdiv(s1, s2):
    #这个处理是保证每个单项式统一格式(coef)*expr
    stmp1 = strmono(s1);
    stmp2 = strmono(s2);

    #乘号的位置
    signIndex1 = stmp1.find('*');
    signIndex2 = stmp2.find('*');
    if (signIndex1 == -1):
        coef1 = stmp1;
        expr1 = '';
    else:
        coef1 = stmp1[:signIndex1];
        expr1 = stmp1[signIndex1+1:];

    if (signIndex2 == -1):
        coef2 = stmp2;
        expr2 = '';
    else:
        coef2 = stmp2[:signIndex2];
        expr2 = stmp2[signIndex2+1:];
        
    coef = coef1+'/'+coef2;
    
    if (signIndex1 == -1 and signIndex2 != -1):
        expr = '('+expr2+')^[-1]';
    elif (signIndex1 == -1 or signIndex2 == -1):
        expr = expr1+expr2;
    else:
        expr = expr1+'/'+expr2;

    if (expr == ''):
        return '('+str(round(eval(coef), 6))+')';
    return '('+str(round(eval(coef), 6))+')*'+expr;
                

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)-1):
        print(strdiv(s[i], s[i+1]));

    for i in range(len(s)-1, 0, -1):
        print(strdiv(s[i], s[i-1]));
		

#找一个字符串中所有待查找子串的位置,返回位置阵列
def findall(string, sub):
    size = len(string);
    index = [];

    cur = string.find(sub);
    index.append(cur)
    
    while (index[-1] != -1):        
        cur = string.find(sub, index[-1]+1);
        index.append(cur);   

    return index;

if __name__ == '__main__':
    #tmp1();
    s = 'abcdefgabcdefgabcdefg';

    print(findall(s, 'c'));
    
#计算单项式的乘方, s^n
def strpow(s, n):
    stmp = strmono(s);
    signIndex = stmp.find('*');
    coef = stmp[:signIndex]+'**'+str(n);
    expr = '('+stmp[signIndex+1:]+')^['+str(n)+']';

    return '('+str(round(eval(coef), 6))+')*'+expr;


    

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)):
        print(strpow(s[i], 3));

#计算代数式用,传入的两个阵列都具有['s1', 's2', ..., 'sn']这样的格式
def strdot(array1, array2):
    size1 = len(array1);
    size2 = len(array2);
    result = [];
    
    for i in range(size1):
        for j in range(size2):
            result.append(strmul(array1[i], array2[j]));

    return result;

    

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];
    s1 = ['3x'];

    answer = strdot(s, s1);
    print(answer);
	
>>> 
['(-3)', '']
['(3)', '']
['(1)', 'x']
['(-1)', 'x']
['(2)', 'x']
['(-2)', 'x']
['(-2)', 'x^[2]']
['(3)', 'x_[2]^[3]']
['(-3)', 'x_[2]^[3]']

#把格式化后的单项式分解成[coef, expr]对组的形式
def explodemono(mono):
    stmp = mono;

    #乘号的位置
    signIndex = stmp.find('*');
    if (signIndex == -1):
        coef = stmp;
        expr = '';
    else:
        coef = stmp[:signIndex];
        expr = stmp[signIndex+1:];

    return [coef, expr];

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)):
        print(explodemono(strmono(s[i])));
		

>>> 
[['(-3)+(3)', ''], ['(1)+(-1)+(2)+(-2)', 'x'], ['(-2)', 'x^[2]'], ['(3)+(-3)', 'x_[2]^[3]']]	
		
#合并同类项,传入的阵列具有['s1', 's2', ..., 'sn']这样的格式
def strcombine(array):
    size = len(array);
    explode = [];
    for i in range(size):
        #这里传入的阵列已经是规格化后的了,否则要加一层strmono处理。
        explode.append(explodemono(array[i]));

    result = [];

    for i in range(size):
        size_1 = len(result);

        if size_1 <= 0:
            result.append(explode[i]);
        else:
            for j in range(size_1):
                if result[j][1] == explode[i][1]:
                    result[j][0] = result[j][0] + '+' + explode[i][0];
                    break;

                if j >= size_1-1:
                    result.append(explode[i]);

    return result;

    

if __name__ == '__main__':
    #tmp1();
    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    result = [];
    
    for i in range(len(s)):
        result.append(strmono(s[i]));

    answer = strcombine(result);
    print(answer);
	
>>> 
[['0', ''], ['0', 'x'], ['-2', 'x^[2]'], ['0', 'x_[2]^[3]']]

    size_1 = len(result);
    for j in range(size_1):
        result[j][0] = str(round(eval(result[j][0]), 6));
		
>>> 
['(0)', '(0)*x', '(-2)*x^[2]', '(0)*x_[2]^[3]']

>>> 
['(0)', '(0)', '(-2)*x^[2]', '(0)']

#合并同类项,传入的阵列具有['s1', 's2', ..., 'sn']这样的格式
def strcombine(array):
    size = len(array);
    explode = [];
    for i in range(size):
        #这里传入的阵列已经是规格化后的了,否则要加一层strmono处理。
        explode.append(explodemono(array[i]));

    result = [];

    for i in range(size):
        size_1 = len(result);

        if size_1 <= 0:
            result.append(explode[i]);
        else:
            for j in range(size_1):
                if result[j][1] == explode[i][1]:
                    result[j][0] = result[j][0] + '+' + explode[i][0];
                    break;

                if j >= size_1-1:
                    result.append(explode[i]);

    result_1 = [];

    size_1 = len(result);
    for j in range(size_1):
        result[j][0] = str(round(eval(result[j][0]), 6));

        if (result[j][0] == '0'):
            result_1.append('(0)');
        else:
            tmps = result[j][1];
            if (tmps == ''):
                result_1.append('('+result[j][0]+')');
            else:            
                result_1.append('('+result[j][0]+')*'+result[j][1]);

    return result_1;
	

>>> 
['(1)*x', '(-1)*y']
['(1)*x*x', '(-1)*x*y', '(-1)*y*x', '(1)*y*y']
['(1)*x*x*x', '(-1)*x*x*y', '(-1)*x*y*x', '(1)*x*y*y', '(-1)*y*x*x', '(1)*y*x*y', '(1)*y*y*x', '(-1)*y*y*y']
[]

#指数为正整数的乘方
def strpow_n(array, n):
    result = [];

    if (n == 1):
        result = array;
    elif (n == 2):
        result = strdot(array, array);

    elif (n == 3):
        tmp = strdot(array, array);
        result = strdot(tmp, array);

    return result;

if __name__ == '__main__':
    #tmp1();
    s = ['x', '-y'];

    array = [];

    for i in range(len(s)):
        array.append(strmono(s[i]));

    s = array;

    print(s);

    result = [];
    
    print(strpow_n(s, 2));
    print(strpow_n(s, 3));
    print(strpow_n(s, 4));
	
#指数为正整数的乘方
def strpow_n(array, n):
    #进行格式化处理
    s = [];

    for i in range(len(array)):
        s.append(strmono(array[i]));

    array = s;

    #计算
    result = [];

    if (n == 1):
        result = array;
    elif (n == 2):
        result = strdot(array, array);

    elif (n == 3):
        tmp = strdot(array, array);
        result = strdot(tmp, array);

    return result;
	
>>> 
['(3)', '(-3)', '(-1)*x', '(1)*x', '(-2)*x', '(2)*x', '(2)*x^[2]', '(-3)*x_[2]^[3]', '(3)*x_[2]^[3]']

#阵列取负
def minus(array):
    for i in range(len(array)):
        if array[i][1] == '-':
            #array[i][0]是'(, 这是规范
            array[i] = array[i][0]+array[i][2:];
        else:
            array[i] = array[i][0]+'-'+array[i][1:];

    return array;

if __name__ == '__main__':
    #tmp2();

    s = ['-3', '3', 'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'];

    for i in range(len(s)):
        s[i] = strmono(s[i]);
        
    result = minus(s);

    print(result);
	</span>


几何运算:

<span style="font-size:18px;">#两点之间
#平面两点的距离[x1, y1] -- [x2, y2]
def distance2D(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    return ((x2-x1)**2+(y2-y1)**2)**0.5;

#平面直线的斜率[x1, y1] -- [x2, y2]
def slope(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    if (x1 == x2):
        return 'inf';
    else:
        return (y2-y1)/(x2-x1);

#平面直线与X轴的夹角[x1, y1] -- [x2, y2]
def angleFromX(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    delta = ((x2-x1)**2+(y2-y1)**2)**0.5;
    dx = x2 - x1;
    dy = y2 - y1;
    
    sin = math.asin(dy / delta)/math.pi*180;
    cos = math.acos(dx / delta)/math.pi*180;

    if (dy >= 0 and dx >= 0):
        return math.asin(dy / delta)/math.pi*180;
    elif (dy >= 0 and dx < 0):
        return 180- math.asin(dy / delta)/math.pi*180;
    elif (dy < 0 and dx <= 0):
        return 180 - math.asin(dy / delta)/math.pi*180;
    else:
        return 360 + math.asin(dy / delta)/math.pi*180;

#平面直线的截距[x1, y1] -- [x2, y2]
def interceptOfLine(Point_1, Point_2):
    k = slope(Point_1, Point_2);

    if k == 'inf':
        return [k, Point_1[0], 1e8];
    elif k == 0:
        return [k, 1e8, Point_1[1]];
    else:
        return [k, Point_1[0]-Point_1[1]/k, Point_1[1]-Point_1[0]*k];
    
#求直线的中垂线
def perpendicular(Line):
    Point_1, Point_2= Line[0], Line[1];
    
    #求斜率
    k = slope(Line[0], Line[1]);
    if k == 'inf':
        k1 = 0;
    else:
        k1 = -1/k;

    midPoint = [0.5*(Point_1[0]+Point_2[0]), 0.5*(Point_1[1]+Point_2[1])];

    return [midPoint, [midPoint[0]+ 10, midPoint[0]+10*k1]];

#两直线之间
#两直线是否平行 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def parallelCheck(Line_1, Line_2):
    L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
    k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);
    if  k1 == k2 == 'inf':
        return True;
    elif k1 != 'inf' and k2 != 'inf' and abs(k1 - k2) < 1e-6:
        return True;

    return False;

#两直线距离 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def lineDistance2D(Line_1, Line_2):
    if parallelCheck(Line_1, Line_2):
        L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
        k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);

        if k1 == 'inf':
            return abs(L1_Point_1[0] - L2_Point_1[0]);
        else:
            dx = L1_Point_1[0] - L2_Point_1[0];
            dy = k1*dx;
            return abs((L2_Point_1[1]+dy-L1_Point_1[1])/(1+k1**2)**0.5);

    else:
        return 0;

#两直线夹角 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def angleBetweenTwoLine(Line_1, Line_2):
    L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];

    return angleFromX(L2_Point_1, L2_Point_2) - angleFromX(L1_Point_1, L1_Point_2);


#两直线交点 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def crossPointOfTwoLine(Line_1, Line_2):
    if not parallelCheck(Line_1, Line_2):
        L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
        '''
        k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);

        if (k1 == 'inf'):
            return [L1_Point_1[0], L2_Point_1[1]-k2*(L2_Point_1[0]-L1_Point1[0])];
        elif (K2 == 'inf'):
            return [L2_Point_1[0], L1_Point_1[1]-k1*(L1_Point_1[0]-L2_Point1[0])];
        '''

        x0, y0, x1, y1, x2, y2, x3, y3 = L1_Point_1[0], L1_Point_1[1], L1_Point_2[0], L1_Point_2[1],\
                                         L2_Point_1[0], L2_Point_1[1], L2_Point_2[0], L2_Point_2[1];
        
        crossY = ( (y0-y1)*(y3-y2)*x0 + (y3-y2)*(x1-x0)*y0 + (y1-y0)*(y3-y2)*x2 + (x2-x3)*(y1-y0)*y2 ) / \
                 ( (x1-x0)*(y3-y2) + (y0-y1)*(x3-x2) );
        crossX =  x2 + (x3-x2)*(crossY-y2) / (y3-y2);

        
        return [crossX, crossY];




#判定三点共线
def pointInLine(Point_1, Point_2, Point_3):
    x0, y0, x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1], Point_3[0], Point_3[1];

    return (x0*y1-y0*x1)+(x1*y2-y1*x2)+(x2*y0-y2*x0) == 0;

#点到直线的距离
def plDistance2D(Point, Line):
    LPoint_1, LPoint_2 = Line[0], Line[1];

    if (pointInLine(Point, LPoint_1, LPoint_2)):
        return 0;
    else:
        k = slope(LPoint_1, LPoint_2);

        if k == 'inf':
            return abs(Point[0]-LPoint_1[0]);
        else:
            Point2 = [Point[0] + 10, Point[1] + 10 * k];
            return lineDistance2D([Point, Point2], Line);
            

#圆 三点成圆  
#以确定的三点表示圆的方程,得到圆心和半径 [x1, y1] -- [x2, y2] -- [x3, y3]
def circle(Point_1, Point_2, Point_3):
    if not pointInLine(Point_1, Point_2, Point_3):
        x1, y1, x2, y2, x3, y3 = Point_1[0], Point_1[1], Point_2[0], Point_2[1], Point_3[0], Point_3[1];

        A1 = 2*(x2-x1);
        B1 = 2*(y2-y1);
        C1 = x2*x2+y2*y2-x1*x1-y1*y1;   
        A2 = 2*(x3-x2);
        B2 = 2*(y3-y2);
        C2 = x3*x3+y3*y3-x2*x2-y2*y2;

        #圆心
        px = ((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1));  
        py = ((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1));

        a = round(distance2D(Point_1, Point_2), 3);
        b = round(distance2D(Point_2, Point_3), 3); 
        c = round(distance2D(Point_3, Point_1), 3);

        #半径
        R = a*b*c/(4*b*b*c*c-(b*b+c*c-a*a)**2)**0.5;

        return [[px, py], R];
    else:
        return [[0, 0], 0];

#判断点和圆的距离 Point:[x, y], Circle: [[x1, y1], [x2, y2], [x3, y3]]
def pointFromCircle(Point, Circle):
    cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
    circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

    d = distance2D(Point, circleCenter);

    #点与圆的位置关系,分为在内部,在外部和在圆上。
    if (d < R):
        return 'IN';
    elif (d > R):
        return 'OUT';
    else:
        return 'ON';


#过圆外部一点,得到与圆的切点的坐标 Point:[x, y], Circle: [[x1, y1], [x2, y2], [x3, y3]]
def tangencyPoint(Point, Circle):
    if pointFromCircle(Point, Circle) == 'OUT':
        cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
        circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

        x1, y1, x2, y2 = circleCenter[0], circleCenter[1], Point[0], Point[1];

        dsquare = (x2-x1)**2+(y2-y1)**2;

        part_1 = (R*R*(y1-y2)**2*(dsquare-R*R))**0.5;
        part_2 = (y1-y2)*dsquare;

        #第一个切点
        x3 = (-part_1+R*R*(x2-x1)+x1*dsquare)/dsquare;
        y3 = ((x1-x2)*part_1-R*R*(y1-y2)**2+y1*part_2)/part_2;
        #第二个切点
        x4 = (part_1+R*R*(x2-x1)+x1*dsquare)/dsquare;
        y4 = (-(x1-x2)*part_1-R*R*(y1-y2)**2+y1*part_2)/part_2;

        return [[x3, y3], [x4,y4]];

    return [[0,0], [0,0]];

#直线到圆的距离
def lcDistance2D(Line, Circle):
    lPoint_1, lPoint_2 = Line[0], Line[1];
    cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];

    circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

    #圆心到直线的距离
    d = plDistance2D(circleCenter, Line);

    return d-R;


#直经与圆的交点
def lcCrossPoint2D(Line, Circle):
    #直线与圆相交
    if lcDistance2D(Line, Circle) <= 0:
        lPoint_1, lPoint_2 = Line[0], Line[1];
        cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
        circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

        k, a, b = interceptOfLine(lPoint_1, lPoint_2);

        if k == 'inf':
            k = 1e8;

        c, d = -circleCenter[0], -circleCenter[1];

        print(k, a, b, c, d, R);

        part_0 = (k*k+1)*R*R-c*c*k*k;
        part_1 = (2*c*d+ 2*b*c)*k- d*d-2*b*d-b*b;
        part_2 = (d+b)*k+c;
        part_3 = d*k*k-b;
        part_4 = (k*k+1);
        
        x1 = -((part_0 + part_1)**0.5+part_2)/part_4;
        y1 = -(k*((part_0+part_1)**0.5 + c)+part_3)/part_4;

        x2 = ((part_0+part_1)**0.5-part_2)/part_4;
        y2 = (k*((part_0+part_1)**0.5 - c)-part_3)/part_4;

        return [[x1, y1], [x2, y2]];

    return [[1e8, 1e8], [1e8, 1e8]];
</span>

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

你可能感兴趣的:([从头学数学] 第210节 带着计算机去高考(二))