Euler#49 Java项目
问题是— 算术序列148748147,其中每个项 增加3330,在两个方面是不寻常的:(i)三项中的每一项 是素数,(ii)每个4位数字都是 一个接一个 没有由三个1、2或3位数字组成的算术序列 素数,表现出这个性质,但还有一个4位数 递增序列 通过将三个术语串联在一起,您形成了什么12位数字 这个序列 我写了这段代码-Euler#49 Java项目,java,permutation,primes,Java,Permutation,Primes,问题是— 算术序列148748147,其中每个项 增加3330,在两个方面是不寻常的:(i)三项中的每一项 是素数,(ii)每个4位数字都是 一个接一个 没有由三个1、2或3位数字组成的算术序列 素数,表现出这个性质,但还有一个4位数 递增序列 通过将三个术语串联在一起,您形成了什么12位数字 这个序列 我写了这段代码- package Problems; import java.util.ArrayList; import java.util.LinkedList; public clas
package Problems;
import java.util.ArrayList;
import java.util.LinkedList;
public class Pro49 {
private static boolean isPrime(int n){
if(n%2 == 0) return false;
for(int i = 3; i<= Math.sqrt(n); i++){
if(n%i == 0) return false;
}
return true;
}
private static boolean isPerm(int m, int n){
ArrayList<Integer> mArr = new ArrayList<>();
ArrayList<Integer> nArr = new ArrayList<>();
for(int i = 0; i<4; i++){
mArr.add(m%10);
m /= 10;
}
for(int i = 0; i<4; i++){
nArr.add(n%10);
n /= 10;
}
return mArr.containsAll(nArr);
}
public static void main(String[] args) {
LinkedList<Integer> primes = new LinkedList<>();
for(int i = 1001; i<10000; i++){
if(isPrime(i)) primes.add(i);
}
int k = 0;
boolean breaker = false;
for(int i = 0; i<primes.size() - 2; i++){
for(int j = i + 1; j<primes.size() - 1; j++){
if(isPerm(primes.get(i), primes.get(j))) {
k = primes.get(j) + (primes.get(j) - primes.get(i));
if(k<10000 && primes.contains(k) && isPerm(primes.get(i), k)) {
System.out.println(primes.get(i) + "\n" + primes.get(j) + "\n" + k);
breaker = true;
break;
}
}
if(breaker) break;
}
if(breaker) break;
}
}
}
包问题;
导入java.util.ArrayList;
导入java.util.LinkedList;
公共类Pro49{
私有静态布尔iPrime(int n){
如果(n%2==0)返回false;
对于(int i=3;i我认为您的逻辑出错的地方是您的isPerm
方法。您使用的是,方法仅检查参数是否至少在集合中一次
i、 基本上是这样的
for(E e : collection)
if(!this.contains(e)) return false;
return true;
因此,例如,4999将是49的排列,因为49包含4和9(而它显然不是基于您的示例)
您的方法对这些值有效的原因是您循环了固定的时间量-即4。对于49这样的数字,您将以{9,4,0,0}
而不是{9,4}
结束。请执行以下操作:
while(n != 0) {
nArr.add(n%10);
n /= 10;
}
您将得到正确的数字列表
s(并看到containsAll
将不起作用。)
在其他位置(例如,在循环中)添加4位限制
也许你可以检查每个数字的出现次数。
例如:
int[] occurrencesA = new int[10], occurrencesB = new int[10];
for(; m != 0; m /= 10)
occurrencesA[m % 10]++;
for(; n != 0; n /= 10)
occurrencesB[n % 10]++;
for(int i = 0; i < 10; i++)
if(occurrencesA[i] != occurrencesB[i]) return false;
return true;
int[]发生率sa=new int[10],发生率sb=new int[10];
对于(;m!=0;m/=10)
发生率a[m%10]++;
对于(;n!=0;n/=10)
发生率b[n%10]++;
对于(int i=0;i<10;i++)
if(occurrencesA[i]!=occurrencesB[i])返回false;
返回true;
我找到了isPerm
private static boolean isPerm(int m, int n){
ArrayList<Integer> mArr = new ArrayList<>();
ArrayList<Integer> nArr = new ArrayList<>();
final String mS = Integer.toString(m);
final String nS = Integer.toString(n);
if(mS.length() != nS.length()) return false;
for(int i = 0; i<mS.length(); i++){
mArr.add(m%10);
m /= 10;
}
for(int i = 0; i<nS.length(); i++){
nArr.add(n%10);
n /= 10;
}
return (mArr.containsAll(nArr) && nArr.containsAll(mArr));
}
private静态布尔值isPerm(int m,int n){
ArrayList mArr=新的ArrayList();
ArrayList nArr=新的ArrayList();
最终字符串mS=Integer.toString(m);
最后一个字符串nS=Integer.toString(n);
如果(mS.length()!=nS.length())返回false;
对于(int i=0;iConcatenating不涉及newlines@1blustone是的,我知道。我只是想看看哪些数字是作为输出生成的,这就是为什么我添加了\n
。只是为了检查置换是否作为输出生成。下面是一个性能有所提高的版本,它首先收集由相同数字组成的素数,请注意在寻找等距数之前:我也这么认为,并检查了我的isPerm(int n)
,但它给了我正确的答案。我甚至检查了你的例子(4999,49),它给了我正确的答案,它们不是排列。我现在注意到isPerm(4999,49)
给出的是假的,但isPerm(999,99)
给出true,然后再次给出isPerm(9999,99)
给出了false。非常奇怪。是的,你说的是对的,但这不应该是个问题,至少在本文中是这样,因为我的素数列表只包含4位素数。@SreevathsaGowru为isPerm
写了一个可能的替代品。是的,它正在工作。看起来我必须检查文档中的内容。无论如何,谢谢!如果要使用字符串,那么最好使用toCharArray
,而不是再次将它们用作数字。