我想找到100亿以下的所有素数。这是int可以容纳的5倍(这是数组的限制,无论类型如何)。尝试一次分配超过12亿,导致堆空间错误。我尝试使用List而不是布尔数组,但arrayLists的set element方法只能索引到int。让我烦恼的是,很快进入筛子的是不到一个整数个元素没有被划掉。应该工作的一种方法是创建一个包含10个数组的分区并将它们粉碎在一起......但这样做会很难看。如果您有任何优雅的解决方法,请告诉我。 (除了使用Python lol)。我已经有一个n ^ 2/2暴力实施,但这需要很长时间才能运行,所以我真的希望尽快解决这个问题。我的Sieve实现工作量高达1.2亿,如下所示:
public class SieveEratosthenes {
private boolean[] nums;
public static void main(String[] args) {
int n = 1000000;
SieveEratosthenes s = new SieveEratosthenes(n);
for(int i=0;i<s.nums.length;i++){
if(s.nums[i]){
System.out.println(i);
}
}
}
public SieveEratosthenes(int max){
sieve(max);
}
private boolean[] sieve(int max){
nums = new boolean[max+1];
initFlags();
for(int i=2;i*i<max;i++){
for(int j=i*i;j<=max;j+=i){//cross off non-primes
nums[j]=false;
}
}
return nums;
}
private void initFlags(){
if(nums != null&&nums.length>1){
nums[0]=false;
nums[1]=false;
nums[2]=true;
}
for(int i=3;i<nums.length;i++){
nums[i]=true;
}
}
public List<Long> sieveToList(){
List<Long> sieveList = new ArrayList();
for(int i=0;i<nums.length;i++){
if(nums[i]){
sieveList.add((long)i);
}
}
return sieveList;
}
答案 0 :(得分:2)
您可以使用以下方法:
PS:如果你想要代码,我会为你做,但我建议你尝试一次。我可能错了,但我认为这种方法就是他们所谓的 $email= mysqli_real_escape_string($db_con,$_POST['email']);
$psw= mysqli_real_escape_string($db_con,$_POST['psw']);
$query = "INSERT INTO `users` (`email`,`psw`) VALUES ('".$email."','".$psw."')";
。
答案 1 :(得分:0)
你应该放弃使用数组。正如你所说,它们不适合非常大的套装。算法的一个合理的近似是“交叉”,因为你通过测试它检查每个素数它是任何先前素数的倍数。我没有分析过这个的表现。
class Sieve {
private long current = 2;
private final List<Long> primes = new ArrayList<>();
public long nextPrime() {
while (primes.stream().anyMatch(p -> current % p == 0))
current++;
primes.add(current);
return current;
}
}
答案 2 :(得分:0)
如果内存不是问题,请继续使用数组,因为它要快得多。如果内存成为问题,我建议调查BitSets。
虽然Java数据结构受限(据我所知)最大int大小约为20亿,但您可以创建自己的数据结构。一个非常简单的解决方案是创建一个类,在给定max int length的情况下将所请求的大小拆分为多个数组或位集,然后自动访问由您输入的长索引输入给出的类。我希望这是有道理的。如果您有任何问题,请告诉我们!