Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException

Ruffyg

Mitglied
Hallöchen,
ich habe mir ein Programm geschrieben um alle Primzahlen in einem fest definierten Bereich heraus zu finden. Dabei habe ich einen Counter eingebaut um zu gucken wie lange mein Laptop für die Rechenoperationen braucht. Das Programm funktioniert bisher auch sehr gut, nur kann ich bei einer Eingabe ab ca. 100000 von einer Fehlermeldung ausgehen.

Java:
package eratosthenes;


import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;

/**
 */
public class Eratosthenes {
    public static void main(String[] args) {

        
        int eingabe = 0;

        
        Scanner in = new Scanner(System.in);

        
        System.out.println("Geben Sie eine ganze Zahl ein, die größer als 1 ist. ");
        
        eingabe = in.nextInt();
      
        do {
            
            if (eingabe <= 1) {
                System.out.println("Ihre Eingabe muss größer als 1 sein.");
                System.out.println("Eingabe einer ganzen Zahl, die größer als 1 ist: ");
                
                eingabe = in.nextInt();
            }
        } while (eingabe <= 1);

        final long startTime = System.nanoTime();
        
        boolean[] teilbar = new boolean[eingabe + 1];

        for (int i = 2; i < teilbar.length; i++) {
            teilbar[i] = false;

        }

      
        for (int i = 2; i < teilbar.length; i++) {
            
            while (teilbar[i]) {   
            
                i++;
            }
            
            for (int j = i; j*i < eingabe; j++) {
                teilbar[i * j] = true;
                
            }
          
            if (! teilbar[i] && i < eingabe) {
                
                System.out.println("Die " + i + " ist eine Primzahl. ");
            }

        }
        final double duration = (System.nanoTime() - startTime)/1000000000.0;
        
        // double zeit = duration/1000000000.0;
        
        System.out.println(duration + " s");
    }
}

Es währe sehr cool wenn mir jemand helfen könnte, ich kann nicht verstehen wie mein Array nicht genügend Felder haben kann.
 
Naja, du inkrementierst `i` der zweiten for-Schleife sowohl in dem Schleifeninkrement der for-Schleife als auch manuell innerhalb der Schleife, prüfst aber beim manuellen Inkrementieren nicht, ob `i` eventuell schon zu groß geworden ist und greifst auch immer einfach auf das Array an der Stelle `i` zu. Danach kann es sehr wohl sein, dass `i` größer ist als das Array:
Java:
for (int i = 2; i < teilbar.length; i++) {   
  while (teilbar[i]) { // <- hier könnte es knallen, nachdem die folgende Anweisung durchlaufen wurde
    i++; // <- hier wird i beliebig weit inkrementiert
  }
  for (int j = i; j*i < eingabe; j++) {
    teilbar[i * j] = true;
  }
  if (! teilbar[i] && i < eingabe) {
    System.out.println("Die " + i + " ist eine Primzahl. ");
  }
}
 
Naja, du inkrementierst `i` der zweiten for-Schleife sowohl in dem Schleifeninkrement der for-Schleife als auch manuell innerhalb der Schleife, prüfst aber beim manuellen Inkrementieren nicht, ob `i` eventuell schon zu groß geworden ist und greifst auch immer einfach auf das Array an der Stelle `i` zu. Danach kann es sehr wohl sein, dass `i` größer ist als das Array:
Java:
for (int i = 2; i < teilbar.length; i++) {  
  while (teilbar[i]) { // <- hier könnte es knallen, nachdem die folgende Anweisung durchlaufen wurde
    i++; // <- hier wird i beliebig weit inkrementiert
  }
  for (int j = i; j*i < eingabe; j++) {
    teilbar[i * j] = true;
  }
  if (! teilbar[i] && i < eingabe) {
    System.out.println("Die " + i + " ist eine Primzahl. ");
  }
}
und wie löse ich das besser?
 
Java:
import java.util.BitSet;
import java.util.stream.IntStream;
import static java.util.stream.IntStream.iterate;
public class Sieve {
    public static IntStream sieve(int n) {
        BitSet notPrime = new BitSet(n);
        int sqrtN = (int) Math.sqrt(n);
        for (int i = 2; i <= sqrtN; i = notPrime.nextClearBit(i + 1))
            for (int j = i * i; j <= n; j += i)
                notPrime.set(j, true);
        return iterate(2, i -> i < n, i -> notPrime.nextClearBit(i + 1));
    }
    public static void main(String[] args) {
        sieve(1000).forEach(i -> System.out.println(i + " ist eine Primzahl."));
    }
}
 
Java:
import java.util.BitSet;
import java.util.stream.IntStream;
import static java.util.stream.IntStream.iterate;
public class Sieve {
    public static IntStream sieve(int n) {
        BitSet notPrime = new BitSet(n);
        int sqrtN = (int) Math.sqrt(n);
        for (int i = 2; i <= sqrtN; i = notPrime.nextClearBit(i + 1))
            for (int j = i * i; j <= n; j += i)
                notPrime.set(j, true);
        return iterate(2, i -> i < n, i -> notPrime.nextClearBit(i + 1));
    }
    public static void main(String[] args) {
        sieve(1000).forEach(i -> System.out.println(i + " ist eine Primzahl."));
    }
}
Diese Zeile
Java:
return iterate(2, i -> i < n, i -> notPrime.nextClearBit(i + 1));

funktioniert nicht, es kommt dieser Fehler

Multiple markers at this line
- The method iterate(int, IntUnaryOperator) in the type IntStream is not applicable for the arguments (int, (<no
type> i) -> {}, (<no type> i) -> {})
- Type mismatch: cannot convert from boolean to int
 

Zurück
Oben