Werte in Felder speichern und geordnet ausgeben

maxmuster987

Aktives Mitglied
Die Aufgabenstellung lautet wie folgt:

Schreiben Sie ein Programm, das das Volumen eines Zylinders in Abhängigkeit vom Durchmesser gestuft in Abständen von einem Millimeter absteigend auf den Bildschirm ausgibt. Eingegeben werden sollen der Start- und der Enddurchmesser (als ganze Zahl).
Ausgegeben werden soll das jeweilige Volumen. Die Höhe ist mit 100mm und PI mit 3,14159626 als Programmkonstante festzulegen. Speichern Sie zuerst die Volumina in einem entsprechend großen Feld und geben Sie das Feld ZUM SCHLUSS aus.
Falls der Enddurchmesser größer ist als der Startdurchmesser, dann sollen die Werte trotzdem in absteigender Reihe sortiert werden.


Java:
import javax.swing.*;
public class Volumina {
    public static void main(String[] args) {
        
        final double PI = 3.1415926;
        final int hoehe = 100;
                
        String eing1 = JOptionPane.showInputDialog("Geben Sie den Startdurchmesser in [mm] ein:");
        int startdurchmesser = Integer.parseInt(eing1);
        
        String eing2 = JOptionPane.showInputDialog("Geben Sie den Enddurchmesser in [mm] ein:");
        int enddurchmesser = Integer.parseInt(eing2);
        
        int intervall = (startdurchmesser-enddurchmesser);
        
        
        if(enddurchmesser>startdurchmesser) {
            enddurchmesser = startdurchmesser;
        }
        
        int feldgroesse = (intervall+1);
        
        System.out.println("Feld mit " +(intervall+1) + " Werten fuer Hoehe 100mm und Startdurchmesser " +startdurchmesser + " mm wurde berechnet");
        
        double feld[] = new double[feldgroesse];
        
            for (int i=startdurchmesser; i>=enddurchmesser; i--)
                
                feld[i] = ((PI*i*i)/4)*hoehe;
            
                int j=feldgroesse;
                
                while (--startdurchmesser >= enddurchmesser)
                System.out.println("Volumen fuer d = " + j + " mm: " + feld[j] + " mm^3");
    }
}

Mein Programm sieht aktuell wie oben aus. Allerdings bekomme ich immer im Compiler die Fehlermeldung
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6"
Wenn ich den Startwert 10 und Endwert 5 verwende als Beispiel.


Ich kann mir schon meinen Fehler denken, dass es mit der Feldvariable was zu tun hat, dass ich das falsch programmiert habe. Der greift aktuell quasi auf die Durchmesserzahlen zurück, aber der soll ja hier in dem Fall auf die Feldelemente 0, 1, 2, 3, 4, 5 mit dem jeweiligen Inhalt der Durchmesser 10, 9, 8, 7, 6, 5. Aber ich weiß noch nicht, wie ich das umzusetzen habe.
Auch die richtige Reihenfolge, falls Enddurchmesser > Startdurchmesser habe ich nicht so ganz eingebracht.
 
Der greift aktuell quasi auf die Durchmesserzahlen zurück

Ja, wenn Du 10 und 5 verwendest, hat das Array eine Größe von 6, mit den Indizes 0 bis 5. In der for-Schleife initialisierst Du i mit dem Startdurchmesser (10) und versuchst nun auf den Index 10 zuzugreifen. Das geht natürlich nicht.

aber der soll ja hier in dem Fall auf die Feldelemente 0, 1, 2, 3, 4, 5 mit dem jeweiligen Inhalt der Durchmesser 10, 9, 8, 7, 6, 5.
Ja, dann mach das doch auch so 🙂 Lass i von 0 bis 5 laufen und dann musst Du in der Schleife ja nur noch 10-i rechnen.
 
Die Antwort erscheint bei genauerem Überlegen recht offensichtlich:
Wie groß das Array ist, hängt bei dir ja von feldgröße und dahinter widerum von intervall und dieses wiederum vom start und enddurchmesser ab.

kannst es ja mal nachrechnen , für die eingabe (10,5) kriegst du:
intervall=10-5=5
also feldgroesse=5+1=6

Das damit erzeugte Array hat also Indexwerte von 0 bis 5.

Und auf welche indexwerte des Arrays greifst du zu?
Na, alle Werte, die das i der for schleife annehmen kann.
Also, so wie dein Code geschrieben ist, Alles von dem Startdurchmesser 10 bis enddurchmesser 5.
was natürlich nicht klappen kann, da die indexwerte von 0 bis 5 gehen.

da kannst du nicht die stelle mit index=10 aufrufen wenn es die gar nicht gibt.

Aber genau genommen sind da noch mancherlei probleme:
Real geht, mit deiner eingabe, die for shcleife von i=10 bis 10.
Warum?
wegen des Abschnitts

Java:
if(enddurchmesser>startdurchmesser) {
            enddurchmesser = startdurchmesser;
        }

Denn hier wird, falls endwert<startwert, einfach der endwert gleich dem endwert gesetzt.
Was Unsinn ist.
Vermutlich wolltest du hier Start und endwert vertauschen, damit es also statt (10,5) mit (5,10) arbeitet.
Das wird so, wie es da steht, nicht erreicht.

Du brauchst da sowas wie
Code:
int hilf=startwert;
startwert=endwert;
endwert=hilf;

Das vertaucscht dir die 2 werte, ohne eine nur für diesen zweck eingeführte hilfsvariable gehts nicht.

Ansosnten solltest du dich mal hinsetzen und überlegen:
gegeben 2 aufsteigende Werte wie (5,10) (nicht aufsteigendes lässt sich ja rumdrehen wie erwähnt).
wie groß muss dein array sein? (der part war übrigens korrekt)
und wie findest du zu jedem der vorkommenden werte die jeweilige indexposition, an der du es einfügen musst?

Also wenn du bspw. die eingabe (2,6) hast (was den schritten 2,3,4,5,6 entspricht)
dann brauchst du, weil eben 6-2+1=5 verschiedene werte, ein array der länge 5.
das die indexwerte 0-4 hat.

wie findest du, gegeben eine der zahlen 2-6, den dazu gehörigen index aus 0-4?
in dem beispiel durch ein -2, also minus den startwert.
denn das bildet 2 auf 2-2=0 ab,
3 auf 3-2=1,
...
6 auf 6-2=4 ab.

Dann musst du halt nur gucken wie du das mit der volumenformel verbindest.


ansonsten verstehe ich nicht ganz, was du da eigentlich in der for shcleife unten versuchst, mit diesem neuen j, dem while und ähnlichem.


Ich hatte die aufgabe so verstanden dass du bspw. bei der eingabe (5,10) (und ebenso bei (10,5))
als ausgabe die werte für volumen(10),volumen(9),volumen(8),volumen(7),volumen(6),volumen(5) erhalten willst.

wozu also in der fo schleife nochmal eine whike schleife, will mir nicht einleuchten :-/
 
Ich habe mal jetzt der Einfachheit halber erst einmal auf das Szenario, dass Endwert > Startwert ist, verzichtet. Damit ich erst einmal das Feld ordentlich ausgeben kann. Danach komme ich auf die Hilfsvariablen zurück.

Code:
import javax.swing.*;
public class Volumina {
    public static void main(String[] args) {
       
        final double PI = 3.1415926;
        final int hoehe = 100;
               
        String eing1 = JOptionPane.showInputDialog("Geben Sie den Startdurchmesser in [mm] ein:");
        int startdurchmesser = Integer.parseInt(eing1);
       
        String eing2 = JOptionPane.showInputDialog("Geben Sie den Enddurchmesser in [mm] ein:");
        int enddurchmesser = Integer.parseInt(eing2);
       
        int intervall = (startdurchmesser-enddurchmesser);
       
        int feldgroesse = (intervall+1);
       
        System.out.println("Feld mit " +(intervall+1) + " Werten fuer Hoehe 100mm und Startdurchmesser " +startdurchmesser + " mm wurde berechnet");
       
        double feld[] = new double[feldgroesse];
       
            for (int i=0; i<=feldgroesse; i++) {
               
                feld[i] = ((PI*((startdurchmesser-i)*(startdurchmesser-i)))/4)*hoehe;
           
                System.out.println("Volumen fuer d = " +(startdurchmesser-i) + " mm: " + feld[i] + " mm^3");
            }
    }
}

Dieser Code ist soweit auch korrekt, also er tut das was ich möchte, sagen wir es mal so. Er berechnet nun von d=10 ... d=5 alle Volumen absteigend.

Aber wenn er diese nun berechnet hat und ausgibt, bekomme ich eine ähnliche Fehlermeldung wie zu Beginn:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 6"


Aber damit ist mir schon mal ein Schritt geholfen dank euch. Nun hänge ich allerdings noch bei den Hilfsvariablen fest, die Start und Enddurchmesser vertauschen sollen, falls End>Start ist. Wie binde ich das hier in den Code mit ein?
 

Anhänge

  • CMD.png
    CMD.png
    13,3 KB · Aufrufe: 4
Zeile 22, < feldgroesse, nicht <= feldgroesse. Der Index eines Arrays der Größe n läuft von 0 bis n-1. Daher < feldgroesse. (EDIT: Variablennamen korrigiert)

Nachtrag:
Nun hänge ich allerdings noch bei den Hilfsvariablen fest, die Start und Enddurchmesser vertauschen sollen, falls End>Start ist. Wie binde ich das hier in den Code mit ein?
Java:
if (startdurchmesser < enddurchmesser) {
    int temp = startdurchmesser;
    startdurchmesser = enddurchmesser;
    enddurchmesser = temp;
}

Alternativ könntest Du auch einfach zwei weitere Variablen einführen, mit denen Du weiterrechnest:
Java:
int minDurchmesser;
int maxDurchmesser;
if (startdurchmesser < enddurchmesser) {
    minDurchmesser = startdurchmesser;
    maxDurchmesser = enddurchmesser;
} else {
    minDurchmesser = enddurchmesser;
    maxDurchmesser = startdurchmesser;
}

int interval = maxDurchmesser - minDurchmesser;
// ...
 
Zuletzt bearbeitet:
if (startdurchmesser < enddurchmesser) { int temp = startdurchmesser; startdurchmesser = enddurchmesser; enddurchmesser = temp; }

Könntest du mir den Schritt eventuell erklären?
Ich habe das eingefügt und das Programm läuft einwandfrei damit.
Ich weiß ehrlich gesagt nur nicht, weshalb es läuft. 😵


Java:
import javax.swing.*;
public class Volumina {
    public static void main(String[] args) {
      
        final double PI = 3.1415926;
        final int hoehe = 100;
              
        String eing1 = JOptionPane.showInputDialog("Geben Sie den Startdurchmesser in [mm] ein:");
        int startdurchmesser = Integer.parseInt(eing1);
      
        String eing2 = JOptionPane.showInputDialog("Geben Sie den Enddurchmesser in [mm] ein:");
        int enddurchmesser = Integer.parseInt(eing2);
              
        if (startdurchmesser<enddurchmesser) {
            int temp = startdurchmesser;
            startdurchmesser = enddurchmesser;
            enddurchmesser = temp;
        }     
              
        int intervall = (startdurchmesser-enddurchmesser);
      
        int feldgroesse = (intervall+1);
      
        System.out.println("Feld mit " +(intervall+1) + " Werten fuer Hoehe 100mm und Startdurchmesser " +startdurchmesser + " mm wurde berechnet");
      
        double feld[] = new double[feldgroesse];
      
            for (int i=0; i<feldgroesse; i++) {
              
                feld[i] = (((PI*((startdurchmesser-i)*(startdurchmesser-i)))/4)*hoehe);
          
                System.out.println("Volumen fuer d = " +(startdurchmesser-i) + " mm: " + feld[i] + " mm^3");
            }
    }
}
 
Zuletzt bearbeitet:
Du möchtest ja sicherstellen, dass der Startdurchmesser größer als der Enddurchmesser ist. Also wird in Zeile 14 geprüft, ob diese Bedingung verletzt ist. Ist dies der Fall merken wir uns in Zeile 15 erst einmal den Startdurchmesser, weil wir diesen in Zeile 16 mit dem Enddurchmesser überschreiben. In Zeile 17 setzen wird den Enddurchmesser auf den gemerkten Startdurchmesser. Insgesamt erreichen wir also ein Vertauschen von Start- und Enddurchmesser, so dass die Bedingung, dass der Startdurchmesser größer als der Enddurchmesser sein muss, wiederhergestellt ist.
 

Neue Themen


Zurück
Oben