20110329 学习记录:1000以内的素数


素数是除了1和它本身以外没有其它约数的数。
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 
139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 223 229 233 239 241 251 257 263 269 271
277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431
433 439 443 449 457 461 463 467 479 487 491 499 503 507 521 523 541 547 563 569 571 577 587 593 599
601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757
761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937
941 947 953 967 971 977 983 991 997
http://baike.baidu.com/view/1767.html?reforce=%D6%CA%CA%FD&hold=synstd

1既不是素数也不是合数它是奇数   

http://www.chinaret.com/user/topic_view.aspx?id=549a8e3d-57b5-4991-8fa7-915135833bee

 
  
// 通过这个例子,我们可以掌握以下知识
// 函数的定义
// 函数的作用:a.使得程序更容易理解 b.可以重复使用代码 c.适合代码封装,团队开发
// C#中函数的调用: 加了static修饰符,则直接可以类结构内调用.没有使用static则只能通过申明对象来调用
// static private public等修饰符的作用

using System;
using System.Collections.Generic;
using System.Text;

namespace Husanhua.TestProgram
{
class Test1
{

static private Boolean IsPrime( int x)
{
Boolean Flag
= true ;
for ( int i = 2 ; i <= Math.Sqrt(x); i ++ ) //注意这里条件应该筛选的是小于等于X平方根的数,
                                 //不然没法筛掉4,25,36...这样的数字

{
if ((x % i) == 0 )
{
Flag
= false ;
}
}
return Flag ;

}
static void Main( string [] args)
{
       int
count = 0;
for ( int i = 2 ; i < 1000 ; i ++ )
{
if ( IsPrime (i)   )
{
            
count++;
Console.Write(i.ToString());
Console.Write(
" " );
}
}
 Console.WriteLine(count); //1000以内素数个数为:168
}
}
}



ContractedBlock.gif ExpandedBlockStart.gif C

 
   
// 判断-200之间有多少个素数,并输出所有素数。

#include
" stdio.h "

#include
" math.h "

main()

{

int n,i;

int num = 0 ;

for (n = 101 ;n <= 200 ;n ++ )

{

for (i = 2 ;i <= sqrt(n);i ++ )

if (n % i == 0 )

break ;

if (i > sqrt(n))

{printf(
" %-7d " ,n);num ++ ;

if (num % 5 == 0 )

printf(
" \n " );

}



}

printf(
" \n\n%d " ,num);

printf(
" \n " );

}


2.
用筛法求素数的方法是:
用质数筛去合数:从第一个素数2开始,把它的倍数去掉;这样2以后的第一个非0数就一定也是素数,把它的倍数也删了……
重复这个删数过程,直到在所找到的素数后再也找不到一个非0数。把所有非0数输出。


ContractedBlock.gif ExpandedBlockStart.gif C

 
   
#include " stdio.h "

#include
" math.h "

main()

{

int i,a[ 1001 ],j,n;

for (i = 1 ;i <= 1000 ;i ++ )

a[i]
= i;

for (i = 2 ;i <= sqrt( 1000 );i ++ )

for (j = i + 1 ;j <= 1000 ;j ++ )

{

if (a[i] != 0 && a[j] != 0 )

if (a[j] % a[i] == 0 )

a[j]
= 0 ;

}

printf(
" \n " );

for (i = 2 ,n = 0 ;i <= 1000 ;i ++ )

{
if (a[i] != 0 )

{printf(
" %5d " ,a[i]);

n
++ ;

}

if (n == 10 )

{printf(
" \n " );n = 0 ;}

}

printf(
" \n " );

}

http://hi.baidu.com/tomatohxy/blog/item/8d4c6a085373a9a82eddd494.html

3.
另外有一种方法,为了减少筛选次数,筛选时只比较奇数



 
  
void main()
{
for ( int i = 3 ; i <= 1000 ; i += 2 ) // 只需要考虑奇数 (我觉得i应该从1开始...
{
bool isNotResult = false ;
for ( int j = 3 ; j <= Math.Sqrt (i); j += 2 )
{
if (i % j == 0 )
{
isNotResult
= true ;
break ;
}
}
if ( ! isNotResult)
{
Console.Writeline(i);
}
}
}

-----------------------------------------------------------------------------------------------------------------------

素数问题总结

关键词 素数 判定 判断 prime 总结 问题 算法

证明:一个合数的所有因子均不大于这个数的开平方
若m不是素数则设m=x*y,其中,m>x,y>1
若x>sqrt(m),则必定y<sqrt(m)
意味着可以在[2,y]的范围内确定m是否素数。
因此只有当y=x=sqrt(m)时,y的范围才是最大值。
即素数的查找范围不大于这个数的开平方。
素数是这样的整数,它除了表示为它自己和1的乘积以外,无论他表示为任何两个整数的乘积。

筛选法思想:

是从2开始用“是则留下,不是则去掉”的方法把所有的数列出来(一直 列到你不想再往下列为止,比方说,一直列到10,000)。第一个数是2,它是一个素 数,所以应当把它留下来,然后继续往下数,每隔一个数删去一个数,这样就能把所有能被2整除、因而不是素数的数都去掉。在留下的最小的数当中,排在2 后面的是3,这是第二个素数,因此应该把它留下,然后从它开始往后数,每隔两个数删去一个,这样就能把所有能被3整除的数全都去掉。下一个未去掉的数是 5,然后往后每隔4个数删去一个,以除去所有能被5整除的数。再下一个数是7,往后每隔6个数删去一个;再下一个数是11,往后每隔10个数删一个;再下 一个是13,往后每隔12个数删一个。就这样依法做下去。
C语言算法
//求1000以内所有素数,用筛选法 
#define SIZE 1000
int main(int argc, char *argv[])
{
  int sign[SIZE];
  int i, j;
  for (i = 0; i < SIZE; i++){
      sign[i] = 1;
  }
  
  for (i = 2; i <= sqrt(SIZE); i++){
      if (sign[i]){
          for (j = 2; j <= SIZE / i; j++){
              sign[i*j]=0;
          }
      }
  }
  
   for (i = 2; i < SIZE; i++){
      if(sign[i])
          printf("%d,",i);
  }
  system("PAUSE");
  return 0;
}
素数判定问题
设N=2^127-1是一个38位数,要验证它是否为素数,有下面几个不同的方法:
1.遍历2以上N的平方根以下的每一个整数,是不是能整除N;(这是最基本的方法)
C语言描述
int isPrimeNumber(int n){
    int i;
    for (i = 2; i <= sqrt(n); i++){
        if (n % i == 0) return 0;
    }
    return 1;
}
2.遍历2以上N的平方根以下的每一个素数,是不是能整除N;(这个方法是上面方法的改进,但要求N平方根以下的素数已全部知道)
但以上算法都不适合长整数的素数判断,通常会采用概率算法。

素数判定概率算法

Rabin -Miller算法是典型的验证一个数字是否为素数的方法。判断素数的方法是Rabin-Miller概率测试,那么他具体的流程是什么呢。假设我们要判 断n是不是素数,首先我们必须保证n 是个奇数,那么我们就可以把n 表示为 n = (2^r)*s+1,注意s 也必须是一个奇数。然后我们就要选择一个随机的整数a (1<=a<=n-1),接下来我们就是要判断 a^s=1 (mod n) 或a^((2^j)*s)= -1(mod n)(0<=j如果任意一式成立,我们就说n通过了测试,但是有可能不是素数也能通过测试。所以我们通常要做多次这样的测试,以确保我们得到的是一 个素数。(DDS的标准是要经过50次测试) 
采用Rabin-Miller算法进行验算
首先选择一个代测的随机数p,计算b,b是2整除p-1的次数。然后计算m,使得n=1+(2^b)m。
(1) 选择一个小于p的随机数a。
(2) 设j=0且z=a^m mod p
(3) 如果z=1或z=p-1,那麽p通过测试,可能使素数
(4) 如果j>0且z=1, 那麽p不是素数
(5) 设j=j+1。如果j且z<>p-1,设z=z^2 mod p,然后回到(4)。如果z=p-1,那麽p通过测试,可能为素数。
(6) 如果j=b 且z<>p-1,不是素数

http://www.cnblogs.com/dengfanxin/archive/2009/08/06/1540697.html

转载于:https://www.cnblogs.com/neru/archive/2011/03/29/1998673.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值