最近遇到很多问题都跟Prime有关,于是总结一下:

Prime definition:A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself. A natural number greater than 1 that is not a prime number is called a composite number. So 1 is not a prime, but 2 is a prime.

性质:

先说composite number:Every composite number has at least one prime factor less than or equal to square root of itself. composite又必须含有divisor other than 1 and itself, 所以必须在[2 ,] inclusive之间有可以整除的prime factor

所以prime number的性质就是:在 [2 ,] inclusive 之间找不到一个数i 使得 n % i == 0

问题1:Efficient program to print all prime factors of a given number

Given a number n, write an efficient function to print all prime factors of n. For example, if the input number is 12, then output should be “2 2 3″. And if the input number is 315, then output should be “3 3 5 7″.

Following are the steps to find all prime factors.
1) While n is divisible by 2, print 2 and divide n by 2.
2) After step 1, n must be odd. Now start a loop from i = 3 to square root of n. While i divides n, print i and divide n by i, increment i by 2 and continue.
3) If n is a prime number and is greater than 2, then n will not become 1 by above two steps. So print n if it is greater than 2.

 // A function to print all prime factors of a given number n
void primeFactors(int n)
{
// Print the number of 2s that divide n
while (n% == )
{
printf("%d ", );
n = n/;
} // n must be odd at this point. So we can skip one element (Note i = i +2)
for (int i = ; i <= sqrt(n); i = i+)
{
// While i divides n, print i and divide n
while (n%i == )
{
printf("%d ", i);
n = n/i;
}
} // This condition is to handle the case whien n is a prime number
// greater than 2
if (n > )
printf ("%d ", n);
}

测试一下上述程序

int main()
{
int n = ;
primeFactors(n);
return ;
}

输出

   

要特别注意12行sqrt(n)中的n是一直随 n = n / i 更新的,而不是始终都是最初始的n。这相当于是在找新的n的prime factor, 而且确定这个新的n的prime factor不包括之前找到过的 i,因为前面已经把小的prime factor全找出来了。反正只要 n 还是 composite number, 那么一定有一个prime factor小于sqrt(n), 那么就一定能找到新的 i 满足条件。找不到就说明 n 不是 composite number了。所以,最后跳出while循环是因为要么n变成了1,要么n变成了质数

当然不这么设置 i 的范围也可以,可以设置 i 从3 到最初的sqrt(n), 或者甚至n,这样可以,但是浪费时间。

How does this work?
The steps 1 and 2 take care of composite numbers and step 3 takes care of prime numbers. To prove that the complete algorithm works, we need to prove that steps 1 and 2 actually take care of composite numbers. This is clear that step 1 takes care of even numbers. And after step 1, all remaining prime factor must be odd (difference of two prime factors must be at least 2), this explains why i is incremented by 2.
Now the main part is, the loop runs till square root of n not till. To prove that this optimization works, let us consider the following property of composite numbers.
Every composite number has at least one prime factor less than or equal to square root of itself.
This property can be proved using counter statement. Let a and b be two factors of n such that a*b = n. If both are greater than , then a.b >  which contradicts the expression “a * b = n”.

In step 2 of the above algorithm, we run a loop and do following in loop
a) Find the least prime factor i (must be less than )
b) Remove all occurrences i from n by repeatedly dividing n by i.
c) Repeat steps a and b for divided n and i = i + 2. The steps a and b are repeated till n becomes either 1 or a prime number.

问题2: 写一个判断自然数n是不是prime的函数

 public class Solution {
public boolean isPrime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i=3; i<=Math.sqrt(n); i=i+2) {
if (n % i == 0) return false;
}
return true;
}
}

Wiki上也给出了这个算法:The property of being prime (or not) is called primality. A simple but slow method of verifying the primality of a given number n is known as trial division. It consists of testing whether n is a multiple of any integer between 2 and . Algorithms much more efficient than trial division have been devised to test the primality of large numbers. Particularly fast methods are available for numbers of special forms, such as Mersenne numbers. As of April 2014, the largest known prime number has 17,425,170 decimal digits.

问题3:

Given a number n, print all primes smaller than or equal to n. It is also given that n is a small number.
For example, if n is 10, the output should be “2, 3, 5, 7″. If n is 20, the output should be “2, 3, 5, 7, 11, 13, 17, 19″.

The sieve of Eratosthenes is one of the most efficient ways to find all primes smaller than n when n is smaller than 10 million or so (Ref Wiki).

Following is the algorithm to find all the prime numbers less than or equal to a given integer n by Eratosthenes’ method:

  1. Create a list of consecutive integers from 2 to n: (2, 3, 4, …, n).
  2. Initially, let p equal 2, the first prime number.
  3. Starting from p, count up in increments of p and mark each of these numbers greater than p itself in the list. These numbers will be 2p, 3p, 4p, etc.; note that some of them may have already been marked.
  4. Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this number (which is the next prime), and repeat from step 3.

When the algorithm terminates, all the numbers in the list that are not marked are prime.

 #include <stdio.h>
#include <string.h> // marks all mutiples of 'a' ( greater than 'a' but less than equal to 'n') as 1.
void markMultiples(bool arr[], int a, int n)
{
int i = , num;
while ( (num = i*a) <= n )
{
arr[ num- ] = ; // minus 1 because index starts from 0.
++i;
}
} // A function to print all prime numbers smaller than n
void SieveOfEratosthenes(int n)
{
// There are no prime numbers smaller than 2
if (n >= )
{
// Create an array of size n and initialize all elements as 0
bool arr[n];
memset(arr, , sizeof(arr)); /* Following property is maintained in the below for loop
arr[i] == 0 means i + 1 is prime
arr[i] == 1 means i + 1 is not prime */
for (int i=; i<n; ++i)
{
if ( arr[i] == )
{
//(i+1) is prime, print it and mark its multiples
printf("%d ", i+);
markMultiples(arr, i+, n);
}
}
}
} // Driver Program to test above function
int main()
{
int n = ;
printf("Following are the prime numbers below %d\n", n);
SieveOfEratosthenes(n);
return ;
}

Summary: Prime的更多相关文章

  1. csu 1756: Prime

    1756: Prime Submit Page   Summary   Time Limit: 3 Sec     Memory Limit: 128 Mb     Submitted: 281    ...

  2. Summary of Critical and Exploitable iOS Vulnerabilities in 2016

    Summary of Critical and Exploitable iOS Vulnerabilities in 2016 Author:Min (Spark) Zheng, Cererdlong ...

  3. 三个不常用的HTML元素:<details>、<summary>、<dialog>

    前面的话 HTML5不仅新增了语义型区块级元素及表单类元素,也新增了一些其他的功能性元素,这些元素由于浏览器支持等各种原因,并没有被广泛使用 文档描述 <details>主要用于描述文档或 ...

  4. Java 素数 prime numbers-LeetCode 204

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  5. Prime Generator

    Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate ...

  6. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  7. [LeetCode] Summary Ranges 总结区间

    Given a sorted integer array without duplicates, return the summary of its ranges. For example, give ...

  8. UVa 524 Prime Ring Problem(回溯法)

    传送门 Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbe ...

  9. Network Basic Commands Summary

    Network Basic Commands Summary set or modify hostname a)     temporary ways hostname NEW_HOSTNAME, b ...

随机推荐

  1. 整理一系列优秀的Android开发源码

    转:http://www.cnblogs.com/feifei1010/archive/2012/09/12/2681527.html 游戏类: 一.15个Android游戏源码(是以andengin ...

  2. 深入学习Make命令和Makefile(上)

    https://www.zybuluo.com/lishuhuakai/note/209302 深入学习Make命令和Makefile(上) make是Linux下的一款程序自动维护工具,配合make ...

  3. php curl-class post

    use \Curl\Curl; $curl = new Curl();$curl->setHeader('Content-Type', 'application/json');$curl-> ...

  4. git上传的文件夹为空的时候

    1,先删除空的文件夹 参考:https://www.cnblogs.com/wang715100018066/p/9694532.html 2,这个只能说是技巧不能说是方法,原理是在每个空文件夹新建一 ...

  5. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α

    实验二十:SDRAM模块③ — 页读写 α 完成单字读写与多字读写以后,接下来我们要实验页读写.丑话当前,实验二十的页读写只是实验性质的东西,其中不存在任何实用价值,笔者希望读者可以把它当成页读写的热 ...

  6. docker参数expose使用

    expose # 暴露端口,但不映射到宿主机,只被连接的服务访问.仅可以指定内部端口为参数 expose: - " - "

  7. 初学lua --lua嵌入c++的一个问题(初始化lua出错,版本问题)

    初学lua.从http://lua-users.org/wiki/CallingLuaFromCpp上下载了一个lua嵌入C++的代码.编译并运行.发现有错误: PANIC: unprotected ...

  8. 解析xml文件的几种技术与Dom4j与sax之间的对比

    一.解析xml文件的几种技术:dom4j.sax.jaxb.jdom.dom 1.dom4j dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常优秀的 ...

  9. 兵器簿之cocoaPods的安装和使用

    以前添加第三方库的时候总是直接去Github下载然后引入,但是如果这些第三方库发生了更新,我们还需要手动去更新项目,所以现在引入之前一直想弄都一直没有弄的cocoaPods,现在演示一把过程 其实非常 ...

  10. Java中为什么需要反射?反射要解决什么问题?

    一句话概括就是使用反射可以赋予jvm动态编译的能力,否则类的元数据信息只能用静态编译的方式实现,例如热加载,Tomcat的classloader等等都没法支持 Java中编译类型有两种: 静态编译:在 ...