题目网址
算法解读
输入
要求
- 1个
- long型整数
算法
质数因子的概念参考
质数因子分解
思路
根据对概念的理解,将算法拆为两块:
- 根据输入long整数,拿到整数内所有的prime质数列表
- 求质数因子
实现
基于jdk11,源码见
github
prime.factors package
输入类 test
public class UserInputReaderTest {
@Test
void inputIsA_positiveInteger() {
LineReaderStub stub = new LineReaderStub();
stub.simulateUserInputs("-1", "abc", "0", "180");
UserInputReader reader = new UserInputReader(stub);
assertThat(reader.readANumber(), is(180L));
}
}
其中stub类用来模拟用户的输入
public class LineReaderStub implements LineReader {
public List<String> userInputs = new ArrayList<>();
private int readOffset = 0;
@Override
public String readLine() {
return userInputs.get(readOffset++);
}
public void simulateUserInputs(String... inputs) {
reset();
Arrays.stream(inputs).forEach(str->userInputs.add(str));
}
private void reset() {
readOffset = 0;
userInputs.clear();
}
}
LineReader接口是被驱动出来的,用来抽象不同种类的介质输入,代码如下
public interface LineReader {
String readLine();
}
输入类 product code
···
public class UserInputReader {
private final LineReader lineReader;
public UserInputReader(LineReader lineReader) { //将输入的异构化作为参数传入,灵活性非常好
this.lineReader = lineReader;
}
public long readANumber() {
long result = -1;
do {
String line = lineReader.readLine();
try {
result = Long.parseLong(line);
} catch (NumberFormatException e) {
System.out.println("please input a number");
}
} while (result <= 0);
return result;
}
}
···
求质数因子 test
public class PrimeFactorTest {
@Test
void calculatePrimeListWithinInputNumber() {
int input = 2;
List<Long> primes = PrimeFactor.getPrimeList(input);
assertThat(primes.size(), is(1));
assertThat(primes.get(0), is(2L));
primes = PrimeFactor.getPrimeList(3L);
assertThat(primes.size(), is(2));
primes = PrimeFactor.getPrimeList(4L);
assertThat(primes.size(), is(2));
primes = PrimeFactor.getPrimeList(5L);
assertThat(primes.size(), is(3));
primes = PrimeFactor.getPrimeList(180L);
assertThat(primes.size(), is(41));
}
@Test
void calcualtePrimeFactor() {
assertThat(PrimeFactor.getPrimeFactor(12), is(Arrays.asList(2L, 2L, 3L)));
assertThat(PrimeFactor.getPrimeFactor(147), is(Arrays.asList(3L, 7L ,7L)));
assertThat(PrimeFactor.getPrimeFactor(17), is(Arrays.asList(17L)));
assertThat(PrimeFactor.getPrimeFactor(180), is(Arrays.asList(2L, 2L, 3L, 3L, 5L)));
}
求质数因子 product code
public class PrimeFactor {
public static List<Long> getPrimeList(long n) {
List<Long> result = new ArrayList<>();
boolean isPrime;
for (long i = 2; i <= n; i++) {
if (i % 2 == 0 && i != 2)
continue; //偶数和1排除
isPrime = true;
for (long j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
result.add(i);
}
}
return result;
}
public static List<Long> getPrimeFactor(long n) {
List<Long> result = new ArrayList<>();
List<Long> primes = getPrimeList(n);
long number = n;
for (Long prime : primes) {
while (number % prime == 0) {
result.add(prime);
number = number / prime;
}
if (primes.contains(number)) {
result.add(number);
break;
}
}
return result;
}
}
ATDD main 端到端测试(用console输入输出)
public class Main {
public static void main(String[] args) {
LineReader lineReader = ()->new Scanner(System.in).nextLine();
UserInputReader userInputReader = new UserInputReader(lineReader);
long inputNumber = userInputReader.readANumber();
List<Long> result = PrimeFactor.getPrimeFactor(inputNumber);
result.forEach(System.out::println);
}
}