使用C# 判断给定大数是否为质数的详解

2016-02-19 09:11 6 1 收藏

下面图老师小编要向大家介绍下使用C# 判断给定大数是否为质数的详解,看起来复杂实则是简单的,掌握好技巧就OK,喜欢就赶紧收藏起来吧!

【 tulaoshi.com - 编程语言 】

C#判断给定大数是否为质数,目标以快速度得到正确的计算结果。
在看到这道题的时候,第一反应这是一道考程序复杂度的题,其次再是算法问题。
我们先来看看质数的规则:
Link:http://en.wikipedia.org/wiki/Prime_number
C#求质数代码:
代码如下:

public bool primeNumber(int n){
             int sqr = Convert.ToInt32(Math.Sqrt(n));
             for (int i = sqr; i 2; i--){
                 if (n % i == 0){
                     b = false;
                 }
             }
             return b;
         }

显然以上代码的程序复杂度为N
我们来优化下代码,再来看下面代码:
代码如下:

public bool primeNumber(int n)
         {
             bool b = true;
             if (n == 1 || n == 2)
                 b = true;
             else
             {
                 int sqr = Convert.ToInt32(Math.Sqrt(n));
                 for (int i = sqr; i 2; i--)
                 {
                     if (n % i == 0)
                     {
                         b = false;
                     }
                 }
             }
             return b;
         }

通过增加初步判断使程序复杂度降为N/2。
以上两段代码判断大数是否质数的正确率是100%,但是对于题干
  1.满足大数判断;
  2.要求以最快速度得到正确结果;
显然是不满足的。上网查了下最快算法得到准确结果,公认的一个解决方案是Miller-Rabin算法
Link:http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
Miller-Rabin 基本原理是通过随机数算法判断的方式提高速度(即概率击中),但是牺牲的是准确率。
Miller-Rabin 对输入大数的质数判断的结果并不一定是完全准确的,但是对于本题来说算是一个基本的解题办法了。
Miller-Rabin C# 代码:
代码如下:

public bool IsProbablePrime(BigInteger source) {
             int certainty = 2;
             if (source == 2 || source == 3)
                 return true;
             if (source 2 || source % 2 == 0)
                 return false;

             BigInteger d = source - 1;
             int s = 0;

             while (d % 2 == 0) {
                 d /= 2;
                 s += 1;
             }

             RandomNumberGenerator rng = RandomNumberGenerator.Create();
             byte[] bytes = new byte[source.ToByteArray().LongLength];
             BigInteger a;

             for (int i = 0; i certainty; i++) {
                 do {
                     rng.GetBytes(bytes);
                     a = new BigInteger(bytes);
                 }
                 while (a 2 || a = source - 2);

                 BigInteger x = BigInteger.ModPow(a, d, source);
                 if (x == 1 || x == source - 1)
                     continue;

                 for (int r = 1; r s; r++) {
                     x = BigInteger.ModPow(x, 2, source);
                     if (x == 1)
                         return false;
                     if (x == source - 1)
                         break;
                 }

                 if (x != source - 1)
                     return false;
             }

             return true;
         }

来源:https://www.tulaoshi.com/n/20160219/1589857.html

延伸阅读
在微软的.NET推出后,关于C#的有关文章也相继出现,作为微软的重要的与JAVA抗衡的语言,C#具有很多优点。本文将选一些C#语言中的重要知识详细介绍, 第一章:参数 1。1 IN 参数 c#种的四种参数形式: 一般参数 in参数 out参数 参数数列 本章将介绍后三种的使用。 在C语言你可以通传递地址(即实参)或是DELPHI语言中通过VAR指示符传递地址参数...
第二章 内存管理 c#内存管理提供了与java一样的自动内存管理功能,让程序员从繁重的内存管理中摆脱出来,内存管理提高了代码的质量和提高了开发效率。 c#限制了着指针的使用,免除了程序员对内存泄漏的烦恼,但是不是意味着向java程序员一样c#程序员在也不能使用指针代来的好处。微软在设计C#语言时考虑到这个问题,在一方面抛弃指针的同时,另...
第三章: 类属性 使用过RAD开发工具的一定inspector很熟悉,程序员通过它可以操作对象的属性,DELPHI中引入了PUBLISH关键字来公布对象属性受到程序员的普遍欢迎.通过存取标志来访问private成员,在c#中有两种途径揭示类的命名属性通过域成员或者通过属性。前者是作为具有公共访问性的成员变量而被实现的;后者并不直接回应存储位置,只是通过存...
如同java一样,在c#中写一个多线程应用是非常简单的,本章将介绍如何在c#种开发多线程程序。在.net中线程是由System.Threading 名字空间所定义的。所以你必须包含这个名字空间。 using System.Threading; 开始一个线程 System.Threading 名字空间的线程类描述了一个线程对象,通过使用类对象,你可以创建、删除、停止及恢复一个线程。创建一个...
类(class)是C#类型中最基础的类型。类是一个数据结构,将状态(字段)和行为(方法和其他函数成员)组合在一个单元中。类提供了用于动态创建类实例的定义,也就是对象(object)。类支持继承(inheritance)和多态(polymorphism),即派生类能够扩展和特殊化基类的机制。使用类声明可以创建新的类。类声明以一个声明头开始,其组成方式如...

经验教程

289

收藏

90
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部