您的位置:首页精文荟萃软件资讯 → C#算法设计与分析-寻找素数

C#算法设计与分析-寻找素数

时间:2004/10/8 13:17:00来源:本站整理作者:蓝点我要评论(0)

    在这篇文章中,我将使用C#编制两个寻找素数的算法,说明算法设计的重要性以及算法的分析。


       素数寻找问题由来已久,一直是一些数学家追求的目的。关于素数的定义及性质,我就不在这里多叙了,相信大家都对此了如指掌。素数的寻找思路比较的简单,根据素数的性质(素数应该不能被除了1和它自身的其他数整除)我们可以从最小的素数2开始,一直到比它小1的数为止,用这些数去整除它,如果它能被整除则它必定不是素数,这是判断单个素数的方法(这个算法思想最简单,时间复杂度最大)。对于寻找比某一个给定的整数值小的所有素数也可以采用这种方法,不过我们会发现,采用这种单个判断的方法所耗的时间比较多。比如查找不大于10的素数,我们必须从2开始一个个判断,共需判断9个数,事实上按照我们后面讲述的方法,只需循环2次就可以了。因此,下面的两种方法都将基于删除法来做。


       我们来看看删除法的思想:


1.  将小于给定整数值n的所有正整数加到一个数组中;


2.  删除能够被一些整数整除的数;


3.  数组中遗留的元素就是最后要得到的素数序列。


对于第二步,我们将给出两种方法来实现。我们先来看看算法:


算法一:


class prime


     {


         public static int[] PrimeList;


         public  static void FindPrime(int n)


         {


              int[] IntList;


              IntList=new int[n];             


              for (int p=2;p<=n;p++) IntList[p-1]=p;


              for (int p=2;p

              {


                   int j=p+1;


                   while (j<=n)


                   {


                       if ((IntList[j-1]!=0 ) && ((IntList[j-1]% p)==0) ) IntList[j-1]=0;


                       j=j+1;


                   }


              }


              int i=0;


              for (int p=2;p<=n;p++)


              {


                   if (IntList[p-1]!=0) i=i+1;


              }


              PrimeList=new int[i];


              i=0;


              for (int p=2;p<=n;p++)


              {


                   if (IntList[p-1]!=0)


                   {


                       PrimeList[i]=IntList[p-1];


                       i=i+1;


                   }                 


              }


         }


     }
 


 


这这个算法中,删除的数是那些被从2开始直到n的平方根的整数整除的数。这个算法比起前面介绍的单个素数的寻找方法要好,它的循环次数减少了一多半,但是这个算法还不是最理想的:


 


1.              例如,6既能被2整除,也能被3整除,那么当p=2时,6被删掉了一次;当p=3时,6又被删除了一次,虽然按照我们设定的算法规则,这不会导致冲突(通过判断IntList数组元素是否为0,若为0就不必重复删除),但是这会使得算法的效率低下。


 


2.              还有计算素数序列元素个数时,我们也走了弯路。第一步,我们先计算出了数组元素大小,第二步才开始赋值,事实上这两步我们可以减去计算数组大小这一步,可以把它放在前面完成。


 


3.              已经被删除了的元素,也就是那些不是素数的元素,可以不用拿他们去整除整数,例如4不用拿去整除8,因为能被4整除的数肯定能被2整除,已经在前面循环中被删除了。


 


基于上述考虑,我们得到了一个效率更加高的算法:


 


class primegood


     {


         public static int[] PrimeList;


         public static void FindPrime(int n)


         {


              int[] IntList;


              int len=n-1;


              IntList=new int[n];


              for (int p=2;p<=n;p++) IntList[p-1]=p;


              for (int p=2;p

              {


                   if (IntList[p-1]==0) continue;


                   int j=p*p;


                   while (j<=n)


                   {


                       if (IntList[j-1]!=0 )


                       {


                            IntList[j-1]=0;


                            len=len-1;


                       }


                       j=j+p;


                   }


              }


              PrimeList=new int[len];


              int i=0;


              for (int p=2;p<=n;p++)


              {


                   if (IntList[p-1]!=0)


                   {


                       PrimeList[i]=IntList[p-1];


                       i=i+1;


                   }                 


              }


         }


     }
 


 


这个算法思想和前面的算法完全一样,不过改正了上面算法中不完善的一些内容。


 


为了说明这两个算法的效率区别,我们编制了如下的主程序来比较一下他们的差异:


 


static void   Main()


         {


              Console.WriteLine("Start!");


              DateTime mytime5=DateTime.Now;


              primegood.FindPrime(100000);


              /*for (int i=0;i<=primegood.PrimeList.Length-1;i++)


              {


                   Console.WriteLine(primegood.PrimeList[i]);


              }*/


              DateTime mytime6=DateTime.Now;


              TimeSpan timeadd3=mytime6-mytime5;


              Console.WriteLine(timeadd3.Ticks);


              DateTime mytime1=DateTime.Now;


              prime.FindPrime(100000);


              DateTime mytime2=DateTime.Now;


              TimeSpan timeadd=mytime2-mytime1;


              DateTime mytime3=DateTime.Now;


              primegood.FindPrime(100000);


              DateTime mytime4=DateTime.Now;


              TimeSpan timeadd2=mytime4-mytime3;


              Console.WriteLine(timeadd.Ticks);


              Console.WriteLine(timeadd2.Ticks);


         }


     }
 


 


通过运行这个程序,可以发现他们的差别是如此的大(前面的算法所耗时间几乎是后面算法的30-60倍),参见下图:



      


    事实上,这两个算法的时间复杂度近似为:⊙(n1.5);⊙(n);可见,对于同一个问题有着多种不同复杂性的算法实现,算法设计是一门十分重要的学问。


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本