求i到j之间的所有质数
第一种方法:效率最差,是把i到j之间的每一个数n,都拿出来,挨个循环用n除以从2到n-1的所有整数,如果期间有一个能整除,那么n是合数,继续下一个。
第二种方法:,效率稍好,比第一种方法效率提高一倍,是把i到j之间的每一个数n,都拿出来,挨个循环用n除以从2到n/2的所有整数,如果期间有一个能整除,那么n是合数,继续下一个。
第三种方法:算法效率就高了很多,利用合数定理——如果一个数是合数,那么它的最小质因数肯定小于等于他的平方根。如50的最小质因数是2,它的平方根是7.07,2<=7.07。也可以用反证法证明。
利用这个原理,只需将i和j之间得某个数n取出,并用循环将n除以从2到根号n之间的所有整数如果期间存在一个数可以整除,那n为合数,否则为质数。
1 class Program 2 { 3 static bool isprimenum(int a) 4 { 5 int i = 2; 6 while (i <= Math.Sqrt(a)) 7 { 8 if (a % i == 0) 9 { 10 Console.WriteLine("您输入的不是素数"); 11 return false; 12 } 13 i++; 14 15 } 16 Console.WriteLine("您输入的是素数"); 17 return true; 18 } 19 static void Main(string[] args) 20 { 21 Console.Write("请输入:"); 22 int num = Console.Read(); 23 isprimenum(num); 24 } 25 26 }
第四种方法:是效率最高的一种方法。首先建立一个布尔型1维数组a,长度为j-i,初始值为true。首先用第三种方法求得i、j之间的第一个质数m。求得m 以后,将所有小于i的m的倍数所在的数组(即a[m的倍数-i])位置全部设为false。然后进行下一步,从n=m++开始,如果a[n-i]已经被设 置为false,则n++,直到出现首个为true的位置p,再将所有小于i的p的倍数所在的数组位置置为false。继续下一步,直到n>根号j 为止,这样所有为true的数组id(如果i=1则0除外,id从1开始)+i 即为质数。
举个例子。例如要查找 2-100之间的质数,首先2是质数,把2的倍数去掉(比如4,6,8,...,100,对应的数组位置是a[m-2]即 a[2],a[4],a[6],...,a[98],将这些位置设为false);进行下一步,此时3没有被去掉(a[2]=true),可认为是质数, 所以把3的倍数去掉(a[5]a[8]a[11],...,a[98]=false);再到5,再到7,7之后呢,因为8,9,10刚才都被去掉了,而 100以内的任意合数的最小质数因子肯定小于等于10(100的开方),所以,去掉,2,3,5,7的倍数后剩下的都是质数了。最后只要将a[id]中所 有等于true的id值加上i输出即可。按照这个例子是id+2,比如0+2,1+2,3+2,...
相对来说这种算法求1到n之间的质数实现起来比较简单,如果是求任意两个数之间的质数,逻辑上会比较复杂。但是,效率的确提高了很多很多。
第四种方法的C#实现代码如下:
1 class Program 2 { 3 static public int ffirst(int n)//找到范围要求内的最小质数,这里为2 4 { 5 int a=2; 6 while (a < n) 7 { 8 int i = 2; 9 while (i <= Math.Sqrt(a)) 10 { 11 if (a % i == 0) 12 { 13 a++; 14 i = 0;//把I置为0,代表已经测得当前这个数不是质数然后跳出循环 15 break; 16 } 17 i++; 18 } 19 if (i != 0) 20 { 21 return a; 22 } 23 24 } 25 return -1; 26 //Console.WriteLine("您输入的是素数"); 27 28 } 29 static void Main(string[] args) 30 { 31 const int N=100;//求1--100之间的质数 32 int Num=ffirst(N); 33 bool[] array=new bool[N];//定义bool类型数组,true代表是质数 34 for (int i = 0; i < array.Length; i++)//赋初值 35 { 36 array[i] = true; 37 } 38 while (Num <= Math.Sqrt(N))//100以内的任意合数的最小质数因子肯定小于等于10(100的开方) 39 { 40 int k = Num;//k存储的是程序执行过程中当前的最小质数,因为 while(!array[Num++]);已经跳过了置为false的数值 41 while (k < N) 42 { 43 if ((k+1) % Num == 0) 44 { 45 array[k] = false; 46 } 47 k++; 48 } 49 //Num++; 50 while(!array[Num++]);//哈哈,终于搞定了!开始怎么都实现不了避开前面已经置为false的数值,就采用了遍历2到N的方法 51 //最后一句代码就搞定了,嘻嘻 52 } 53 54 for (int x = 1; x < N; x++) 55 { 56 if (array[x]) 57 { 58 Console.Write((x+1)+" "); 59 } 60 } 61 } 62 } 63 }