1,小学生版本:
判断 x 是否为质数,就从 2 一直算到 x-1。
如果这道题目有10分,按照这种方式做出的代码,即便正确无误,也只能给1分。
- static rt_uint32_t array1[ARRAY_LEN];
- void func1(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++)
- {
- array1[i - 1] = 0;
- }
-
- rt_uint32_t x, y = 0, z = 0;
- rt_uint32_t i = 0;
- for (x = 2; x <= ARRAY_LEN; x++)
- {
- y = 0;
- for (i = 1; i <= x; i++)
- {
- if (x % i == 0)
- {
- y++;
- }
- }
- if (y == 2)
- {
- z++;
- array1[x - 1] = x;
- }
- }
- array1[0] = 1;
- }
2,小学生毕业版:
x 如果有质因数,肯定会小于等于 x/2,所以捏,就从 2 一直到 x/2 即可。
- static rt_uint32_t array2[ARRAY_LEN];
- void func2(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++)
- {
- array2[i - 1] = 0;
- }
-
- rt_uint32_t x, y = 0, z = 0;
- rt_uint32_t i = 0;
- for (x = 3; x <= ARRAY_LEN; x++)
- {
- y = 0;
- for (i = 2; i <= x / 2; i++)
- {
- if (x % i == 0)
- {
- y++;
- break;
- }
- }
- if (y == 0)
- {
- z++;
- array2[x - 1] = x;
- }
- }
- array2[0] = 1;
- array2[1] = 2;
- }
3,初中生版:
除了2以外的质因数都是奇数。所以算从3开始一直到 x/2 的所有奇数。
- static rt_uint32_t array3[ARRAY_LEN];
- void func3(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++)
- {
- array3[i - 1] = 0;
- }
-
- rt_uint32_t x, y = 0, z = 0;
- rt_uint32_t i = 0;
- for (x = 3; x <= ARRAY_LEN; x += 2)
- {
- y = 0;
- for (i = 2; i <= x / 2; i++)
- {
- if (x % i == 0)
- {
- y++;
- break;
- }
- }
- if (y == 0)
- {
- z++;
- array3[x - 1] = x;
- }
- }
- array3[0] = 1;
- array3[1] = 2;
- }
4,高中生版:
其实只要从 2 一直尝试到根号x,就可以了。因为x只要有因数必定有一个因数小于等于根号x。
简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。至于严密的数学证明,用小学数学知识就可以搞定。
- static rt_uint32_t array4[ARRAY_LEN];
- void func4(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++)
- {
- array4[i - 1] = 0;
- }
-
- rt_uint32_t x, y = 0, z = 0;
- rt_uint32_t i = 0;
- for (x = 3; x <= ARRAY_LEN; x++)
- {
- y = 0;
- for (i = 2; i <= sqrt(x); i++)
- {
- if (x % i == 0)
- {
- y++;
- break;
- }
- }
- if (y == 0)
- {
- z++;
- array4[x - 1] = x;
- }
- }
- array4[0] = 1;
- array4[1] = 2;
- }
5,本科生版:
把上面的版本都综合起来
- static rt_uint32_t array5[ARRAY_LEN];
- void func5(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++)
- {
- array5[i - 1] = 0;
- }
-
- rt_uint32_t x, y = 0, z = 0;
- rt_uint32_t i = 0;
- for (x = 3; x <= ARRAY_LEN; x += 2)
- {
- y = 0;
- for (i = 2; i <= sqrt(x); i++)
- {
- if (x % i == 0)
- {
- y++;
- break;
- }
- }
- if (y == 0)
- {
- z++;
- array5[x - 1] = x;
- }
- }
- array5[0] = 1;
- array5[1] = 2;
- }
6,本科生毕业版本:
就是当i是质(素)数的时候,i的所有的倍数必然是合数。如果i已经被判断不是质数了,那么再找到i后面的质数来把这个质
数的倍数筛掉。
筛法如何求质数,说起来很简单:
首先,2是公认最小的质数,所以,先把所有2的倍数去掉;然后剩下的那些大于2的数里面,最小的是3,所以3也是质数;然后把所有3的倍数都去掉,剩下的那些大于3的数里面,最小的是5,所以5也是质数......
上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。维基百科上有一张很形象的动画,能直观地体现出筛法的工作过程。
- static rt_uint32_t array6[ARRAY_LEN];
- void func6(void)
- {
- for (rt_uint32_t i = 1; i <= ARRAY_LEN; i += 2)
- {
- array6[i - 1] = i;
- }
-
- for (rt_uint32_t i = 3; i < sqrt(ARRAY_LEN); i+=2)
- {
- if (array6[i-1])
- {
- for(rt_uint32_t j=i<<2;j<=ARRAY_LEN;j+=i)
- {
- array6[j] = 0;
- }
- }
- }
- array6[1] = 2;
- }