[算法]求最大公约数的算法

数学计算上往往要用到公约数,所以将我已知的3种求公约数的方法进行了测试。

1。欧拉方法(名字记不真切了)

  public static int Gcd_2(int M , int N)
  {                                                            
   if(M > N)                                              
    return Gcd_2(M - N, N );                  
   else if (M < N)                                     
    return Gcd_2(M , N - M );                 
   else                                                      
    return M;                                              
  
}                                                              

原理:M,N是已知的2数,加入 K | M && K|N 则必然有 K | ( M - N )

2。欧拉方法的变体——求余法(自己编的名字)

  public static int Gcd_1(int M , int N)
  {                                                            
   int Rem;                                             
                                                               
   while( N > 0)                                     
   {                                                           
    Rem = M % N;                                 
    M = N;                                                
    N = Rem;                                         
   }                                                          
   return M;                                            
  }                                                           

原理:利用求余来减少重复相减的次数

3。最“无敌的方法”——穷举

  public static int Gcd_3(int M , int N)          
  {                                                                        
   int i;                                                                 
   int Num=Min3(M , N , Math.Abs( M - N ) );
   for(i=Num;i>=2;i--)                                      
    if(M%i==0 && N%i==0)                             
     return i;                                                        
   return 1;                                                        
  }                                                                       
                                                                          
  public static int Min3(int a , int b , int c )   
  {                                                                      
   if(a<b)                                                           
    if(a<c)                                                           
     return a;                                                     
    else                                                             
     return c;                                                     
   else                                                              
    if(b<c)                                                          
     return b;                                                     
    else                                                             
     return c;                                                     
  }                                                                      

原理:当然是穷举了,一个一个试,最基本的就是1个循环搞定,没必要讨论,我进行了一些改变,就是从M,N,M-N 3者中找最小值再逐渐减小取值。

-------------------------------------------------------我是可恶的分割线----------------------------------------------------------------------

实验:

先是实验代码

ps.我为了做实验才去msdn看了下计时器System.Timers.Timer类,也许使用上有什么问题,望高手提出建设性的意见 : )

using System;                                                          
using System.Timers;                                            

namespace Algorithm.Gcd                                   
{                                                                                  
 public class Program                                            
 {                                                                                 
  static int n;                                                               
                                                                                   
  public static void Main(string [] args)                
  {                                                                               
   Program.n=0;                                                       
                                                                                   
   if(args.Length!=2)                                               
    return;                                                                   
   int a,b;                                                                   
   a=int.Parse(args[0]);                                           
   b=int.Parse(args[1]);                                           
   Timer time=new Timer(0.0001);                      
   time.Elapsed+=new ElapsedEventHandler(On_TimeRun);
   int i;                                                                        
   time.Start();                                                          
   for(i=0;i<100000;i++)                                         
    Algorithm.Gcd_1(a,b);                                      
   Console.WriteLine("#1 Time run {0} ",n);      
   Console.WriteLine(Algorithm.Gcd_1(a,b));   
   time.Stop();                                                          
                                                                                  
   Program.n=0;                                                     
   time.Start();                                                         
   for(i=0;i<100000;i++)                                        
    Algorithm.Gcd_2(a,b);                                     
   Console.WriteLine("#1 Time run {0}",n);      
   Console.WriteLine(Algorithm.Gcd_2(a,b)); 
   time.Stop();                                                        
                                                                                
   Program.n=0;                                                    
   time.Start();                                                        
   for(i=0;i<100000;i++)                                       
    Algorithm.Gcd_3(a,b);                                    
   Console.WriteLine("#1 Time run {0} ",n);   
   Console.WriteLine(Algorithm.Gcd_3(a,b));
   time.Stop();                                                       
   time.Close();                                                    
  }                                                                           
  private static void On_TimeRun(object sender,ElapsedEventArgs e)
  {                                                                             
   Program.n++;                                                   
  }                                                                            
 }                                                                             
}                                                                              

可能使用上会有问题,不过因该数据上差别不大

这样测试一下是非常简单的,各位自己去实验下就可以了

鄙人测试能力不佳,斗胆放出我的一点测试数据

数字1                           数字2                               算法1时间                                算法2时间                 算法3时间              

10                                     20                                        0                                                  0                                7

 10                                     21                                       5                                                  6                              11 

  13                                  39                                         3                                                  2                              3 

   13                                    42                                      6                                                   4                            13

 -------------------------------------------------------下面是较大的数据--------------------------------------------------------------------

10234                          92106                                     3                                                  3                                3

10234                          15351                                     4                                                   1                                3

-------------------------------------------------------下面的数据看的我一阵寒------------------------------------------------------------

10234                          127925                                   4                                                   6                          3966

---------------------------------------------------------又作了一次,继续寒----------------------------------------------------------------

10234                          127925                                   4                                                   6                           3932

 

ps.最后将同样的数据作了2次,每次cpu占用都达到了55%,我的cpu P4 双核 3.0 MHz。

各位根据情况来选择吧 : )

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值