三种常用算法概述——遍试、迭代、递归
算法:
为解决某类问题而设计的操作序列(非可执行的指令序列)
特点:有穷性、确定性、可行性、输入输出
1、遍试算法:
逻辑上:针对所有的可能的情况进行判断
形式上FOR中用IF示例:
- 韩信点兵
<span style="white-space:pre"> </span>using System; class HanXin { static void Main() { for(int n=1;n<=105;n++) if(n%3==2 && n%5==3 && n%7==5) Console.WriteLine(n); } }
- 水仙花数:1^3+5^3+3^=153
<span style="white-space:pre"> </span>using Systen; public class ShuiXianHua { public static void Main(string[] args) { for(int a=1;a<=9;a++) for(int b=0;b<=1;b++) for(int c=1;c<=9;c++) if(a*a*a+b*b*b+c*c*c==100*a+10*b+c) Console.WriteLine } }
运行结果:153、370、371、407
但人们目前最多知道11位的,随着位数增大,耗时增大,然后就算不出来了。
- 完全数:28=1+2+4+7+14
<span style="white-space:pre"> </span>using System; class WanQuanShu { public static void Main(string[] args) { for(int n=1;n<=9999;n++) if(n==divsum(n)) Console.WriteLine(n); } public static void divsum(int n) { int s=0; for(int i=1;i<=n;i++) if (n%i==0) s+=1; return s; } }
- 相亲数:M的约数之和等于N的约数之和。算法和完全数有些类似
<span style="white-space:pre"> </span>using System; class XiangQinShu { public static void Main(string[] args) { for(int n=1;n<=9999;n++) { int s=divsum(n) if(n<s && divsum(s)==n) Console.WriteLine(n+","+s); } } public static void divsum(int n) { int s=0; for(int i=1;i<=n;i++) if (n%i==0) s+=1; return s; } }
运行结果:220,284;1184,1210;2620,2924……
- 验证歌德巴猜想:任何一个偶数都能表示成两个质数之和。
<span style="white-space:pre"> </span>using System; class GeDeBaCaiXiang { static void Main() { for(int n=6;n<=100;n+=2) { for(int a=3;a<n/2;a+=2) int b=n-a; if(IsPrime(a)&&IsPrime(b)) { Console.WriteLine(n+"="+a+"+"+b); break; } } } static bool IsPrime(int a) { for(int i=2;i<=a/2;i++) { if(s%i==0) return false; return true; } } }
其他:百鸡问题、鸡兔同笼问题、百分比、佩尔方程
2、迭代:一步一步逐渐精确。
逻辑上:多次使用同一算法。
形式上:a=f(a)
示例:
- 求平方根
<span style="white-space:pre"> </span>using System; public class Sqrt { public static void Main(string [] args){ Console.WriteLine( sqrt( 98) ); Console.WriteLine( Math.Sqrt(2.0) ); } static double sqrt( double a ){ double x=1.0; do{ Console.WriteLine( x + ", " + a/x ); x = ( x + a/x ) /2; }while( Math.Abs(x*x-a)/a > 1e-6 ); return x; } }
- 倍边法求Pi
<span style="white-space:pre"> </span>using System; class TestDebugPi { static void Main() { double a=1; for(int n=1; n<=10; n++ ) { a = Math.Sqrt(2 - Math.Sqrt(4 - a * a)); double pi = a * 3 * Math.Pow(2,n); Console.WriteLine( pi ); } Console.WriteLine( Math.PI ); } }
其他:数字平方和、Mandelbrot集、Julia集
3、递归:分治思想,递归出口+递归主体
逻辑上:一个问题华为同样的问题
形式上:自己调用自己
示例:
- 求阶乘
<span style="white-space:pre"> </span>using System; public class Fac { public static void Main(string [] args) { Console.WriteLine("Fac of 5 is " + fac( 5) ); } static long fac( int n ){ if( n==0 || n==1) return 1; else return fac(n-1) * n; } }
- 斐波那契数列
<span style="white-space:pre"> </span>using System; public class Fibonacci { public static void Main(string [] args) { Console.WriteLine("Fibonacci(10) is " + fib(10) ); } static long fib( int n ){ if( n==0 || n==1) return 1; else return fib(n-1) + fib(n-2); } }
- Celay树
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; public class Form1 : Form { public Form1() { this.AutoScaleBaseSize = new Size(6, 14); this.ClientSize = new Size(600, 400); this.Paint += new PaintEventHandler(this.Form1_Paint); } static void Main() { Application.Run(new Form1()); } private void Form1_Paint(object sender, PaintEventArgs e) { graphics = e.Graphics ; drawTree( 10, 200, 310, 100, -PI/2 ); } private Graphics graphics; const double PI = Math.PI; double th1 = 40 * Math.PI / 180; double th2 = 30 * Math.PI / 180; double per1 = 0.6; double per2 = 0.7; void drawTree(int n, double x0, double y0, double leng, double th) { if( n==0 ) return; double x1 = x0 + leng * Math.Cos(th); double y1 = y0 + leng * Math.Sin(th); drawLine(x0, y0, x1, y1, n/2); drawTree( n - 1, x1, y1, per1 * leng, th + th1 ); drawTree( n - 1, x1, y1, per2 * leng, th - th2 ); } void drawLine( double x0, double y0, double x1, double y1, int width ){ graphics.DrawLine( new Pen(Color.Blue, width ), (int)x0, (int)y0, (int)x1, (int)y1 ); } } Celay树2:支随机持 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; public class Form1 : Form { public Form1() { this.AutoScaleBaseSize = new Size(6, 14); this.ClientSize = new Size(400, 400); this.Paint += new PaintEventHandler(this.Form1_Paint); this.Click += new EventHandler( this.Redraw ); } static void Main() { Application.Run(new Form1()); } private void Form1_Paint(object sender, PaintEventArgs e) { graphics = e.Graphics ; drawTree( 10, 200, 380, 100, -PI/2 ); } private void Redraw(object sender, EventArgs e) { this.Invalidate(); } private Graphics graphics; const double PI = Math.PI; double th1 = 35 * Math.PI / 180; double th2 = 25 * Math.PI / 180; double per1 = 0.6; double per2 = 0.7; Random rnd = new Random(); double rand() { return rnd.NextDouble(); } void drawTree(int n, double x0, double y0, double leng, double th) { if( n==0 ) return; double x1 = x0 + leng * Math.Cos(th); double y1 = y0 + leng * Math.Sin(th); drawLine(x0, y0, x1, y1); drawTree( n - 1, x1, y1, per1 * leng * (0.5+rand()), th + th1* (0.5+rand()) ); drawTree( n - 1, x1, y1, per2 * leng * (0.4+rand()), th - th2* (0.5+rand()) ); if(rand()>0.6) drawTree( n - 1, x1, y1, per2 * leng * (0.4+rand()), th - th2* (0.5+rand()) ); } void drawLine( double x0, double y0, double x1, double y1 ){ graphics.DrawLine( Pens.Blue, (int)x0, (int)y0, (int)x1, (int)y1 ); } }
其他:Koch分形集
小结:
遍试:FOR中用IF
迭代:WHILE中a=F(a);
递归:F(n)中用F(n-1);
本文在学习唐大仕老师在网易云课堂中C#公开课后编辑而成,再此表示感谢!
如有转载请请务必保留此出处:http://www.cnblogs.com/xiangyangzhu/