一、题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 )
最后一个数后面也要有空格
二、代码实现
1、从2遍历到num,如果一个数是素数,并且可以被num整除,则将其添加到结果中
代码中for循环有两个出口,一个是当 i 增加到num时,一个是当遍历过程中num变为1时。但其实第二个不需要,因为num的变化就已经影响了控制条件i < num。
在这道题中可能因为输入没有long型的素数,所以下面的代码for循环的循环变量 i 定义成 int 型可以通过。但是,如果是素数2147483659(超过int的取值范围),则会因为 i 导致死循环。所以最好将 i 定义成 long。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLong()) {
Long num = sc.nextLong();
StringBuilder sb = new StringBuilder();
for (int i=2; i<=num; ) {
while (isPrime(i) && num%i == 0) {
sb.append(i+" ");
num = num / i;
}
if (num == 1) { //提前退出
break;
}
if (i == 2) {
i++;
} else {
i += 2;
}
}
System.out.println(sb.toString());
}
}
public static boolean isPrime(int a) {
for (int i=2; i<Math.sqrt(a); i++) {
if (a % i == 0) {
return false;
}
}
return true;
}
}
2、不使用StringBuilder,直接在循环中打印
这种方式在处理2147483659的输入时不会出现问题。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long input;
while (sc.hasNextLong()) {
input = sc.nextLong();
long sqrtOfInput = (long) Math.sqrt(input);
for (long i=2L; i<=sqrtOfInput; i++) {
//出口2 i==sqrtOfInput
while (input%i == 0) {
System.out.print(i + " ");
input /= i;
}
if (input == 1) { //出口1
break;
}
}
if (input != 1) { //input为素数的情况
System.out.print(input +" ");
}
}
}
}
3、下面的写法也可以在输入为2147483659时避免溢出,不过运行与第二种相比较慢
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Long num = sc.nextLong();
for (long i=2L; i<=num; i++) {
while (num%i == 0) {
System.out.print(i+" ");
num = num / i;
}
}
}
}
可以按照第二种方式那样予以改进
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long num = sc.nextLong();
long sqrtNum = (long)Math.sqrt(num);
for (long i=2L; i<=sqrtNum; i++) {
while (num%i == 0) {
System.out.print(i+" ");
num = num / i;
}
}
if (num != 1) {
System.out.print(num+" ");
}
}
}