[从头学数学] 第174节 算法初步

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[算法初步]。

正剧开始:

星历2016年04月12日 08:54:58, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[算法初步]。


[人叫板老师]指点小伟说:“这金丹要想大成,顺利进入元婴期,就必须进行九转培炼。
这什么是九转培炼法门呢?就是要先快速的修炼[天地人正册]进入后期,不要管各种辅修
功法,然后从头游历[天地人列国],在游历中增长见闻,精炼神通,最后再修炼[术、流、
动、静]这些法门的辅修功法。这样,自然可以做到金丹成就,神通无敌。“


[人叫板老师]又说:”现在这修仙界,各宗派林立,都广收弟子门人,传授修习功法。但
是这些宗派,无非是采用题海试炼术,这三天一摸骨,五天一粹体的,走的是偏门神通。
这些加入各门各派的修士,又贪图各门派的神通术法,东学一招,西练一式,最终所学驳
杂不纯,难得真传。所谓事倍功半者也。“


小伟说道:”老师所言,学生岂会不知,学生自然只会修习老师所传功法。其它各门各派
,纵然把自家功法说得千好万好,天花乱坠,地涌金泉,学生也不会理会的。“


[人叫板老师]对小伟的回答很满意,说:”如是如是,所谓题海无边,回头是岸。又曰题
海茫茫,不渡的才是高手。你要能把我功法中的各国游历完毕,自然是真传在手,天下我
有。”


于是两人抚掌大笑。


[从头学数学] 第174节 算法初步_第1张图片






<span style="font-size:18px;">import math;

def tmp(N):
    if prime(N):
        print(N, '是质数。');
    else:
        print(N, '不是质数。');


#判断一个数是否质数
def prime(num):
    if (num < 2):
        return False;
    
    sqr = int(math.sqrt(num))+1;

    for i in range(2, sqr):
        if (num%i==0):
            return False;

    return True;

if __name__ == '__main__':
    tmp(7);
    tmp(35);</span>


>>> 
7 是质数。
35 不是质数。


一般来说,知道了一个数不是质数,总想分解一下质因数看看,

可以这样去做:

<span style="font-size:18px;">#分解质因数
def primeFactor(num, lists):
    if (num < 2):
        lists.append(num);
        return lists;
    elif (prime(num) == True):
        lists.append(num);
        return lists;
    else:    
        sqr = int(math.sqrt(num))+1;
        i = 2;

        while i <= sqr:
            if (num % i == 0 and prime(i) == True):
                lists.append(i);
                num = num//i;
                break;
            
            i+=1;
        return primeFactor(num, lists);       </span>


>>> 
7 是质数。
35 不是质数。
123456123457 不是质数。
[5, 7]
[7]
[47, 1039, 2528129]


<span style="font-size:18px;">    tmp(7);
    tmp(35);
    tmp(123456123457);
    print(primeFactor(35, []));
    print(primeFactor(7, []));
    print(primeFactor(123456123457, []));</span>

[从头学数学] 第174节 算法初步_第2张图片


<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, 1);          
            
        //坐标轴设定    
        var scaleX = 2*r, scaleY = 2*r;      
        var spaceX = 2, spaceY = 2;       
        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 = [];   
              
        //需要显示的函数说明    
        var f1 = 'y=x*x-2';
        //函数描点    
        for (var x = xS; x <= xE; x+=0.3) {      
            if (x != 0) {    
                a.push([x, funTask(x)]);    
  
  
  
  
            }    
        }      
  
        //二分法求函数的零点  
        //区间的最小值和最大值  
        var minX = 0, maxX = 4;  
        var y1 = y2 = 0;  
        x = minX;  
        y1 = funTask(x);  
        x = maxX;  
        y2 = funTask(x);  
          
        //如果在给定区间上存在有零点  
        if (y1 * y2 < 0) {  
            var epsilon = 0.000001;  
            while (Math.abs(y1-y2) > epsilon) {  
              
                x = minX;  
                y1 = funTask(x);  
                x = maxX;  
                y2 = funTask(x);  
                  
                  
                x = (minX+maxX)/2;  
                y = funTask(x);  
                  
                if (y * y1 < 0) {  
                    maxX = x;  
                }  
                else {  
                    minX = x;  
                }  
                  
  
            }  
            plot.setFillStyle('blue')  
                .fillText('零点:x = '+ ((minX+maxX)/2).toFixed(3), -200, -60, 120);  
        }  
             
			 
		//存放临时数组    
        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, -90, 200);      
        }    
            
    
    }</span>


<span style="font-size:18px;">function funTask(x) {  
    return x*x-2;  
}  	</span>



[从头学数学] 第174节 算法初步_第3张图片



[从头学数学] 第174节 算法初步_第4张图片

[从头学数学] 第174节 算法初步_第5张图片

[从头学数学] 第174节 算法初步_第6张图片


现在小伟有两种方法可以知道一个三角形的面积,

第一种是:

<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 = 2*r;
	
		//三角形的三边长度
		var a = 3, b = 4, c = 5;
		var triangle = new Triangle();
		var transform = new Transform();
		var array = triangle.know3edges([a, b, c]);
		
		shape.angleDraw(transform.translate(array, -200/scale, 0), 'cyan', scale);  
        shape.areaDraw(array, 'red', scale);  

	}</span>

[从头学数学] 第174节 算法初步_第7张图片


第二种是:


>>> 
三角形的面积是: 6.0


<span style="font-size:18px;">#海伦-秦九韶公式
def HQFormula(a, b, c):
    p = (a+b+c)/2;
    S = math.sqrt(p*(p-a)*(p-b)*(p-c));

    return S;
  

if __name__ == '__main__':
    print('三角形的面积是:', HQFormula(3, 4, 5));</span>



<span style="font-size:18px;">>>> 
-5 -> 100
-4 -> 110
-3 -> 102
-2 -> 82
-1 -> 56
0 -> 30
1 -> 10
2 -> 2
3 -> 12
4 -> 46
5 -> 110

def poly(x):
    return ((x+3)*x-24)*x+30;

if __name__ == '__main__':
    for x in range(-5, 6):
        print(x, '->', poly(x));</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 scaleX = 2*r, scaleY = 2*r;      
        var spaceX = 2, spaceY = 50;       
        var xS = -10, xE = 10;      
        var yS = -100, yE = 200;      
        config.axisSpacing(xS, xE, spaceX, scaleX, 'X');        
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');        
                
        var transform = new Transform();        
        //存放函数图像上的点    
        var a = [];   
              
        //需要显示的函数说明    
        var f1 = 'y=x^3+3x^2-24x+30';
        //函数描点    
        for (var x = xS; x <= xE; x+=0.3) {      
            if (x != 0) {    
                a.push([x, funTask(x)]);    
  
  
  
  
            }    
        }      
  
        //二分法求函数的零点  
        //区间的最小值和最大值  
        var minX = 0, maxX = 4;  
        var y1 = y2 = 0;  
        x = minX;  
        y1 = funTask(x);  
        x = maxX;  
        y2 = funTask(x);  
          
        //如果在给定区间上存在有零点  
        if (y1 * y2 < 0) {  
            var epsilon = 0.000001;  
            while (Math.abs(y1-y2) > epsilon) {  
              
                x = minX;  
                y1 = funTask(x);  
                x = maxX;  
                y2 = funTask(x);  
                  
                  
                x = (minX+maxX)/2;  
                y = funTask(x);  
                  
                if (y * y1 < 0) {  
                    maxX = x;  
                }  
                else {  
                    minX = x;  
                }  
                  
  
            }  
            plot.setFillStyle('blue')  
                .fillText('零点:x = '+ ((minX+maxX)/2).toFixed(3), -200, -60, 120);  
        }  
             
			 
		//存放临时数组    
        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, -90, 200);      
        }    
            
    
    }
	



function funTask(x) {  
    return Math.pow(x, 3)+3*Math.pow(x, 2)-24*x+30;  
}  	</span>

[从头学数学] 第174节 算法初步_第8张图片




[从头学数学] 第174节 算法初步_第9张图片

[从头学数学] 第174节 算法初步_第10张图片


<span style="font-size:18px;">>>> 
step 1 :  8251 6105
step 2 :  6105 2146
step 3 :  2146 1813
step 4 :  1813 333
step 5 :  333 148
step 6 :  148 37
37

def gcd(m, n):
    m, n = max(m, n), min(m, n);
    i = 1;
    while n:
        print('step', i, ': ', m, n);
        i += 1;
        m, n = n, m % n
        
    return m

if __name__ == '__main__':
    print(gcd(8251, 6105));
</span>



[从头学数学] 第174节 算法初步_第11张图片




>>> 
step 1 :  98 63
step 2 :  63 35
step 3 :  35 28
step 4 :  28 7
7




<span style="font-size:18px;">#秦九韶公式计算多项式的值
def poly(x, coef):
    #coef为多项式按次数从高到低排列的系数矩阵
    rank = len(coef);
    result = 0;

    for i in range(rank):
        result *= x;
        result += coef[i];
    return result;

if __name__ == '__main__':
    print(poly(5, [1,1,1,1,1,1]));</span>


>>> 
3906


[从头学数学] 第174节 算法初步_第12张图片

<span style="font-size:18px;">>>> 
14130.2

#秦九韶公式计算多项式的值
def poly(x, coef):
    #coef为多项式按次数从高到低排列的系数矩阵
    rank = len(coef);
    result = 0;

    for i in range(rank):
        result *= x;
        result += coef[i];
    return result;

if __name__ == '__main__':
    print(poly(5, [4,2,3.5,-2.6,1.7,-0.8]));</span>


<span style="font-size:18px;">>>> 
0.0014992598466277984

if __name__ == '__main__':
    print(poly(0.477, [4,2,3.5,-2.6,1.7,-0.8]));</span>


<span style="font-size:18px;">>>> 
-0.21984000000000004
-0.1959787996000001
-0.17082158719999996
-0.14428610279999987
-0.11628759039999992
-0.08673874999999975
-0.05554968959999984
-0.022627877199999813
0.01212190720000017
0.048797619600000286

if __name__ == '__main__':
    x = 0.4;
    while (x < 0.5):
        print(poly(x, [4,2,3.5,-2.6,1.7,-0.8]));
        x += 0.01;</span>




[从头学数学] 第174节 算法初步_第13张图片


<span style="font-size:18px;">>>> 
89 --> 1011001

def dec2bin(N):
    s = '';
    a = [];
    
    a.append(N%2);
    N//=2;
    while N > 0:
        a.append(N%2);
        N//=2;

    size = len(a);
    for i in range(size):
        s += str(a[size-i-1]);
    return s;

if __name__ == '__main__':
    N = 89;
    print(N, '-->', dec2bin(N));</span>



<span style="font-size:18px;">>>> 
89 --> 1011001
89 --> 131
89 --> 59
>>> ================================ RESTART ================================
>>> 
1024 --> 10000000000
1024 --> 2000
1024 --> 400
>>> ================================ RESTART ================================
>>> 
255 --> 11111111
255 --> 377
255 --> FF

def dec2k(N, k):
    s = '';
    a = [];
    #只提供了36进制数以内的唯一表示对照表
    if k > 36:
        return '';
    
    charTable = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    a.append(N%k);
    N//=k;
    while N > 0:
        a.append(N%k);
        N//=k;

    size = len(a);
    for i in range(size):
        s += charTable[a[size-i-1]];
    return s;
    

if __name__ == '__main__':
    N = 255;
    print(N, '-->', dec2k(N, 2));
    print(N, '-->', dec2k(N, 8));
    print(N, '-->', dec2k(N, 16));</span>

[人叫板老师]这里之所以限制k要在10以内,是担心数字不够用,

但小伟这里还有字母加入,不用担心这个问题,

所以最多可以扩充到36进制。

<span style="font-size:18px;">>>> 
108 --> 1101100
108 --> 154
108 --> 6C
108 --> 30
</span>
<span style="font-size:18px;">

    print(N, '-->', dec2k(N, 16));
    print(N, '-->', dec2k(N, 36));</span>

梁山108将,在36进制下也就刚好三个方阵。


[从头学数学] 第174节 算法初步_第14张图片

<span style="font-size:18px;">if __name__ == '__main__':
    #1
    task = [[225,135],[98,196],[72,168],[153,119]];

    for i in range(len(task)):
        print(gcd(task[i][0], task[i][1]));

    #2
    print(poly(5, [0.83,0.41,0.16,0.33,0.5,1]));

    #3
    N = 2008;
    print(N, '-->', dec2k(N, 2));
    print(N, '-->', dec2k(N, 8));
    print(N, '-->', dec2k(N, 16));
    print(N, '-->', dec2k(N, 32));
    print(N, '-->', dec2k(N, 36));

>>> 
step 1 :  225 135
step 2 :  135 90
step 3 :  90 45
45
step 1 :  196 98
98
step 1 :  168 72
step 2 :  72 24
24
step 1 :  153 119
step 2 :  119 34
step 3 :  34 17
17
2881.749999999999
2008 --> 11111011000
2008 --> 3730
2008 --> 7D8
2008 --> 1UO
2008 --> 1JS</span>


[从头学数学] 第174节 算法初步_第15张图片

<span style="font-size:18px;">function funTask(x) {  
    return 0.83*Math.pow(x, 5)+0.41*Math.pow(x,4)+0.16*Math.pow(x, 3)+0.33*Math.pow(x, 2)+0.5*x+1;  
}  	</span>


[从头学数学] 第174节 算法初步_第16张图片



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



你可能感兴趣的:([从头学数学] 第174节 算法初步)