2009-08-15 12 views
2

Je prends une classe Java débutant, avec l'affectation de créer un programme d'histogramme avec la sortie suivante: (100 et 10 sont des entrées utilisateur).Début Java (Histogramme)

Combien de nombres? 100 Combien d'intervalles? Mon code donne la sortie suivante cependant, quelqu'un peut-il m'aider à signaler ce qui ne va pas, merci beaucoup.

How Many Numbers? 10 
How Many Intervals? 10 

Histogram 
-------------------------------------------------------- 
1 **********(10) 
2 **********(10) 
3 **********(10) 
4 **********(10) 
5 **********(10) 
6 **********(10) 
7 **********(10) 
8 **********(10) 
9 **********(10) 
10 **********(10) 

Pour l'entrée, 100 et 10 je reçois le message d'erreur:

Exception dans le thread "principal" java.lang.ArrayIndexOutOfBoundsException: 10 à Lab6.main (Lab6.java:44 J'ai marqué la ligne 44 ci-dessous.

Quels liens vers ce code;

   intervalValue[j]++; 

Je ne sais pas comment fixer le générateur (.jar), il est censé simplement générer les aléatoires # 's pour nous. Merci encore.

mport java.util.Scanner; 

public class Lab6 { 

    public static void main(String[] args) { 

     int numbers, intervals; 
     double intervalWidth; 

     double max, mins, range; 

     Scanner keyboard = new Scanner(System.in); 

     System.out.print("How Many Numbers? "); 

     numbers = keyboard.nextInt(); 

     System.out.print("How Many Intervals? "); 

     intervals = keyboard.nextInt(); 

     double [] generate = new double[numbers]; 

     generate = randomGenerator(numbers); 

     max = maximum(generate); 

     mins = minimum(generate); 

     range = max - mins; 

     intervalWidth = range/intervals; 

     int [] intervalValue = new int[intervals]; 

     for (int i=0; i < generate.length; i++) { 

      for (int j = 0; j<generate.length; j++){ 
       double imin = mins+j*intervalWidth; 
       double imax = max +j*(intervalWidth); 
       if(generate[i] >= imin && generate[i] < imax) 
        intervalValue[j]++;   //LINE 44 
      } 
     } 

     System.out.println("Histogram"); 

     System.out.println("--------------------------------" + 
          "------------------------"); 

     for (int a=0; a < intervalValue.length; a++) { 

      System.out.print(" " + (a+1) + " "); 

      for (int b=0; b < intervalValue[a]; b++) { 
       System.out.print("*"); 
      } 

      System.out.println("(" + intervalValue[a] + ")"); 
     } 
    } 

    private static double [] randomGenerator(int number) { 
     double [] generate; 

     generate = Generator.getData(number); 

     return generate; 
    } 

    private static double maximum(double [] a) { 

     double max = a[0]; 

     for (int i = 1; i < a.length; i++) {   
      if (a[i] > max) { 
       max = a[i]; 
      }   
     } 

     return max; 
    } 

    private static double minimum(double [] a) { 

     double mins = a[0]; 

     for (int i = 1; i < a.length; i++) { 
      if (a[i] < mins) { 
       mins = a[i]; 
      } 
     } 

     return mins; 
    } 
} 
+0

Malheureusement, je ne peux pas compiler sans votre classe de générateur. – Kekoa

+1

et vous voudrez peut-être envisager d'utiliser un formateur de code (eclipse en a intégré) n'essayez pas de publier le contenu des fichiers binaires. Ça n'aide pas :) –

Répondre

0

Utilisez un EDI comme Eclipse, exécutez votre programme et voyez où se trouve la ligne 44. C'est là que vous obtenez votre ArrayIndexOutOfBoundsException et c'est là que vous devez vous assurer que vous ne sortez pas des obligations. Les tableaux en java ont leur premier item à l'index 0, donc un tableau de 10 items les fera numéroter 0,1,2,3,4,5,6,7,8,9. Si cela arrive à 10, vous itérez probablement un pas de loin. Assurez-vous que j dans "intervalValue [j]" n'est pas 10 lorsque vous y arrivez.

Sans l'exception complète, source qui compile ni les numéros de ligne corrects dans la source que vous avez collé. Il n'y a plus grand chose à faire. Comprendre cela vous aidera à acquérir autant de connaissances que le reste du laboratoire vous donnera. Essayez-le bien.

2

Vous devez supprimer le point-virgule de la fin de la ligne 43:

if(generate[i] >= imin && generate[i] < imax); 

Le point-virgule provoque votre bloc if être vide. Par conséquent, la ligne résultant de l'exception est exécutée sans condition.

Une fois que vous répondiez à cette question, voici quelques conseils pour vous aider à démarrer sur la poursuite de débogage de votre code:


Jetez un oeil à la condition de terminaison de la boucle intérieure:

for (int j = 0; j<generate.length; j++) 

Vous effectuez l'itération sur les nombres générés dans votre boucle externe; Vous devriez donc parcourir les intervalles de votre boucle interne pour déterminer l'intervalle auquel appartient chaque nombre généré.


Jetez un oeil au code que vous utilisez pour déterminer les limites de l'intervalle courant dans votre boucle:

double imin = mins+j*intervalWidth; 
double imax = max +j*(intervalWidth); 

Ces lignes doivent être modifiées pour obtenir les valeurs correctes. Faites un peu de «débogage crayon-papier» pour déterminer pourquoi ils sont actuellement dans l'erreur.


Je vais laisser le reste comme un exercice pour le lecteur pour le moment. Je reviendrai plus tard pour voir si vous avez besoin d'aide supplémentaire.

+0

+1 Bon point, je l'ai raté. – Fredrik

0
intervalValue[j]++; 

j est monte au nombre de numéros, mais intervalValue est alloué à partir du nombre d'intervalles, si ces deux chiffres ne sont pas les mêmes, vous obtiendrez l'erreur que vous voyez ici.

+0

Comment puis-je les rendre identiques, ou au moins ne pas créer l'erreur? -Merci, – Benzle

0

Votre tableau d'exception semble provenir de l'utilisation de generate.length à deux reprises - bien que votre code collé semble être modifié à partir de cela.

Cependant, à part cela, le problème réside dans vos boucles imbriquées. En dehors de la mauvaise taille de tableau dans la première des boucles internes, vous allez dans le bon sens. Ensuite, à l'instruction if - vous voulez incrémenter cette valeur, et cette valeur seule si elle est dans le bon intervalle; avec votre code actuel, vous incrémentez chacun d'eux à chaque fois, ce qui explique la sortie.

Prendre votre propre code, et de commenter:

for (int i=0; i < generate.length; i++) { 

    for (int j = 0; j<intervals; j++){ // could use intervalValues.length here; it's all preference 
    double imin = mins+j*intervalWidth; 
    double imax = mins +(intervalWidth)*(j+1); 
    if(generate[i] >= imin && generate[i] < imax) 
     // for(int j1 = 0; j1 < intervalValue.length; j1++) <- this was causing the bad output 
     /* I assume the j1 from your code was during a debug attempt. Changed back, 
      since the preceeding loop has been removed */ 
     intervalValue[j]++; 


    } 

} 
2

Depuis que je me sentais généreux un samedi, je l'ai essayé et récrit votre boucle.

for (int j=0; j < generate.length; j++) { 
    for(int i = 0; i < intervals; i++) { 
     double imin = mins + i * intervalWidth; 
     double imax = mins + (intervalWidth) * (i + 1); 
     if(i == intervals - 1) imax = Double.POSITIVE_INFINITY; 
     if(i == 0) imin = Double.NEGATIVE_INFINITY; 

     if (generate[j] >= imin && generate[j] < imax) { 
      intervalValue[i]++; 
      break; 
     } 
    } 
} 

L'infini est d'attraper les min et max de l'histogramme.

+0

Merci beaucoup à tous, ce fut une excellente première expérience de dépassement de pile! – Benzle

1

Cela vous donnera un très bel histogramme (basique). Essayez

import java.util.HashMap; 
import java.util.Map; 

public class Histogram { 
    public static void main(String[] args) { 
     int[] age = { 25, 26, 33, 26, 27, 21, 26, 33, 21, 33, 21, 38, 19, 19}; 


     HashMap<Integer, Integer> m = new HashMap<Integer, Integer>(); 

     for (int i = 0; i < age.length; i++) { 
      int c = 0; 

      for (int j = 0; j < age.length; j++) { 
       if (age[i] == age[j]) { 
        c++; 
       } 
      } 
      m.put(age[i], c); 

     } 

     System.out.println("Histogram\n------------"); 
     for (Map.Entry<Integer, Integer> entry : m.entrySet()) { 
      int key = entry.getKey(); 
      int value = entry.getValue(); 
      System.out.printf("%3d | ", key); 
      for (int i = 0; i < value; i++) { 
       System.out.print("="); 
      } 
      System.out.print(" " + value); 
      System.out.println(); 
     } 

    } 

outout:

Histogram 
------------ 
33 | === 3 
19 | == 2 
21 | === 3 
38 | = 1 
25 | = 1 
26 | === 3 
27 | = 1 

J'utilise HashMap pour maintenir deux valeurs liées à savoir l'un élément de tableau et sa fréquence (la fréquence il semble).

Puis une boucle imbriquée boucle en boucle par chaque élément le long du tableau et compte sa fréquence en utilisant la variable c.

Après que je l'imprimer avec boucle for-each et boucle normale

+0

Pourriez-vous expliquer le code en quelques mots? Cela rendra votre réponse tellement meilleure et vous pourrez obtenir plus de votes. – Andrei

+0

J'utilise HashMap pour garder deux valeurs liées à savoir l'élément d'un tableau et sa fréquence (à quelle fréquence il apparaît). Ensuite, une boucle imbriquée boucle chaque élément le long du tableau et compte sa fréquence en utilisant la variable "c". Après que je l'ai imprimé avec amélioré pour boucle et boucle normale – Amjad

+0

Ajouté votre explication à la réponse. Dans la fonction n'oubliez pas d'expliquer votre code :) Bon travail! – Andrei

Questions connexes