问题:求n以内的所有素数。要求给出自然语言描述的算法,并且实现算法。事先分析算法的时间复杂度和空间复杂度。/*如果错误或相关改进的欢迎提出,谢谢!*/

/*2018.10.20上传,该贴还有部分需要完善,比如2输不出,还有许多可以优化的地方,未完,待更~~*/

#include <stdio.h>
#include <math.h>
#include <time.h>
void prime(int n);
int main()
{
    unsigned int n;
    clock_t start, end;
    start = clock();
    printf("请输入你要查找素数的最大范围:");
    while (!scanf_s("%d", &n))
    {
        fflush(stdin);//清理缓存
        printf("请输入合法字符,请重新输入:");
    }
    printf("以下为2~%d的所有素数\n", n);
    prime(n);
    end = clock();
    printf("耗时%d毫秒\n", end - start);
    system("pause");
    return 0;
}
void prime(int n)
{
    int i, j;
    for (i = 3; i <= n; i += 2)
    {
        for (j = 2; j <= sqrt(i); j++)
        {
            if (i%j == 0)
            {
                break;
            }
        }
        if (j>sqrt(i))//输出素数,因为一个素数开根号会小于这个数与之右相临的数
        {
            printf("%8d", i);
        }
    }
}
/*2018.10.22晚所写*/

自然语言描述的算法:

目标:求n以内的所有素数

素数的定义:只能被1和它自己整除,而不能被其他自然数整除的数,1除外

涉及的相关原理:一素数的的最大公因数必定小于这个素数的算数开平方根        

一、从键盘内读入2~n范围内的整数;

二、再筛选掉2~n以内的偶数;

三、筛除的2又为素数,因此进行单独输出;

四、从3~n以内的奇数开始循环筛选,如这个数能被从2到这个数的算数开平方根整除,则跳出循环;如果不能(判断条件:因为一个素数开根号会小于这个数与之右相临的数),则输出这个数,即为素数;

扫描二维码关注公众号,回复: 3954812 查看本文章

 

时间复杂度:因为首先n以内的偶数先排除,剩n/2个数(n>2)),从3开始,因此第一次循环理论上执行(n-2)/2次,第二次循环从2开始至√n,执行√n-1次,执行次数为(n-2)*( n-1)/2因为数量级涉及至n,因此程序中其语句执行次数都基本上可以忽略,所以才程序的时间复杂度为O(n^(3/2));

 

空间复杂度:因为在筛选当中之运用到了i,j两个变量,因此空间复杂度为O(1);

#include <stdio.h>

#include <math.h>

#include <time.h>

void prime(int n);

int main()

{

    unsigned int n;// 无符号整型范围为 4394967295,输入该数的最大范围

    clock_t start, end;//定义初始时间,利用clock函数计算程序运行时所花的时间长短

    start = clock();

    printf("请输入你要查找素数的最大范围:");

    while (!scanf_s("%d", &n))//运用scanf函数的返回值,如果输入的不是一个数,则返回0.反之,则返回1

    {

         fflush(stdin);//清理缓存

         printf("请输入合法字符,请重新输入:");

    }

    printf("以下为2~%d的所有素数\n", n);

    prime(n);

    end = clock();

    printf("耗时%d毫秒\n", end - start);

    system("pause");

    return 0;

}

void prime(int n)

{

    int i, j,isPrime=2;//isPrime=2,对2进行单独输出

if(n==2)

         printf("%8d",n);

    for (i = 3; i <= n; i += 2)//筛除所有的偶数

    {

         printf("%8d", isprime);

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

         {

             if (i%j == 0)

             {

                  break;

             }

         }

         if (j>sqrt(i))//输出素数,因为一个素数开根号会小于这个数与之右相临的数

         {

             printf("%8d", i);

         }

    }

}

事后统计:1000以内用时1478ms左右;

                   10000以内用时2000ms左右;

                   20000以内用时2500ms左右;

                   100000以内用时7000ms左右;

                         理论上,这个数小于等4394967295,都可对其进行测试

以下为1000以内的素数:

 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     227     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     509     521     523     541     547     557     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

猜你喜欢

转载自blog.csdn.net/sinat_41803693/article/details/83245351