Мой массив запоминает только последний введенный элемент, и гистограмма печатается неправильно

#java #arrays #histogram

Вопрос:

 import java.util.Scanner;

public class RainRecording {

    private int choice;
    private Scanner input;
    private String site;
    private int days;
    private int daysCounter;
    private int[] rainRecorded;
    private int[] rainEntered;
    private float lattitude;
    private float longitude;
    private String message1;
    private String message2;
    private String message3;
    private String message4;
    private String message5;
    private String message6;

    // declare name of variable

    public RainRecording() {

        // declare value of variable

        this.message1 = "Site";
        this.message2 = "lattitude";
        this.message3 = "longitude";
        this.message4 = "Window";
        this.message5 = "days";
        this.message6 = ":";
        this.daysCounter = 0;
        this.input = new Scanner(System.in);
        mainMenu();

    }

    private void mainMenu() {
        System.out.println("");
        System.out.println("*** Rain Gauge Menu ***");
        System.out.println("  1: Create rain gauge");
        System.out.println("  2: Display rain gauge details");
        System.out.println("  3: Add daily rainfall measurement");
        System.out.println("  4: Display rainfall histogram");
        System.out.println("  5: Get maximum rainfall");
        System.out.println("  6: Check rainfall is below threshold");
        System.out.println("  7: Display anaylsis");
        System.out.println("  8: Exit");
        System.out.print("Please enter your selection: ");

        Chosen();

    }

    private void Chosen() {

        this.choice = Integer.parseInt(input.nextLine());
        switch (choice) {
        case 1:
            createGauge();
            break;

        case 2:

            gaugeDetails();
            break;
        case 3:
            
            int i = 0;

            while( i < this.days || this.daysCounter == this.days) {
            
            if (this.daysCounter == this.days) {

                System.out.printf("Error - system fulln");
                mainMenu();

            }
            if (this.days < 1) {

                mainMenu();

            } else {        
                

                this.rainRecorded = new int[this.days];
                System.out.printf("Please enter rainfall for the current day:  ");
                rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
                this.daysCounter  ;
                this.rainEntered = new int[this.daysCounter];
                mainMenu();
            }
            
            i  ;
            }
            break;
        case 4:
            System.out.printf("n");
            displayHistogram();
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            break;
        case 8:
            break;

        default:
            System.out.println("Invalid input, try again");
            mainMenu();
        }

        while (choice != 8)
            ;

    }

    

    private void createGauge() {

        System.out.printf("nPlease enter the name of the site :");
        this.site = input.nextLine();
        System.out.printf("Please enter the number of days to record :");
        this.days = Integer.parseInt(input.nextLine());
        System.out.printf("Please enter the lattitute :");
        this.lattitude = Float.parseFloat(input.nextLine());
        System.out.printf("Please enter the longitude :");
        this.longitude = Float.parseFloat(input.nextLine());
        mainMenu();

    }

    private void gaugeDetails() {

        if (this.days > 0) {

            System.out.printf("%-9s %-3s %s n", this.message1, this.message6, this.site);
            System.out.printf("%s %-3s % 09.4fn", this.message2, this.message6, this.lattitude);
            System.out.printf("%s %-3s %9.4fn", this.message3, this.message6, this.longitude);
            System.out.printf("%-9s %-3s %-2d%s n", this.message4, this.message6, this.days, this.message5);

            mainMenu();

        } else {

            mainMenu();

        }

    }

    private void displayHistogram() {

        for (int i = 0; i < this.rainEntered.length; i  ) {

            for (int j = 0; j < this.rainRecorded[i] - 1; j  ) {

                System.out.print("*");

            }

            System.out.println(i);

        }

        System.out.print("");
        mainMenu();

    }

    public static void main(String[] args) {

        @SuppressWarnings("unused")
        RainRecording objName;
        objName = new RainRecording();

    }

}
 

Я, ребята , я был поражен этим в течение нескольких дней в своем заявлении о переключении в случае 3, где я создаю свои элементы для ввода в свой массив, но, похоже, помню только последний массив, введенный, когда я распечатываю свою гистограмму в случае 4, отображаю гистограмму(); и именно здесь моя гистограмма также печатается неправильно.
Итак, к вопросам мой массив не записывает свойство, и гистограмма печатается неправильно.
Например, пользователи выбирают 3 дня для ввода, а значения равны 10,20,30, и когда я печатаю гистограмму, она печатает это.

 0    
1  
*****************************2
 

Что я хочу , чтобы это было ниже, один * навсегда десять мельниц дождя с индексом, напечатанным первым.

 0 *              
1 **  
2 **  
 

Комментарии:

1. Вы создаете новый экземпляр this.rainRecorded = new int[this.days]; в своем while-loop , так что только последний из них когда-либо будет назначен

Ответ №1:

Вам нужно переместить инициализацию this.rainRecorded createGauge метода to и обновить метод displayHistogram для печати по мере необходимости. Вы можете попробовать следующее:

 import java.util.Scanner;

public class RainRecording {

  private int choice;
  private Scanner input;
  private String site;
  private int days;
  private int daysCounter;
  private int[] rainRecorded;
  private int[] rainEntered;
  private float lattitude;
  private float longitude;
  private String message1;
  private String message2;
  private String message3;
  private String message4;
  private String message5;
  private String message6;

  // declare name of variable

  public RainRecording() {

    // declare value of variable
    
    this.message1 = "Site";
    this.message2 = "lattitude";
    this.message3 = "longitude";
    this.message4 = "Window";
    this.message5 = "days";
    this.message6 = ":";
    this.daysCounter = 0;
    this.input = new Scanner(System.in);
    mainMenu();
  }

  private void mainMenu() {
    System.out.println("");
    System.out.println("*** Rain Gauge Menu ***");
    System.out.println("  1: Create rain gauge");
    System.out.println("  2: Display rain gauge details");
    System.out.println("  3: Add daily rainfall measurement");
    System.out.println("  4: Display rainfall histogram");
    System.out.println("  5: Get maximum rainfall");
    System.out.println("  6: Check rainfall is below threshold");
    System.out.println("  7: Display anaylsis");
    System.out.println("  8: Exit");
    System.out.print("Please enter your selection: ");
    Chosen();
  }

  private void Chosen() {
    this.choice = Integer.parseInt(input.nextLine());
    switch (choice) {
      case 1:
        createGauge();
        break;
      case 2:
        gaugeDetails();
        break;
      case 3:
        int i = 0;
        while( i < this.days || this.daysCounter == this.days) {
          if (this.daysCounter == this.days) {
            System.out.printf("Error - system fulln");
            mainMenu();
          }
          if (this.days < 1) {

            mainMenu();

          } else {
            System.out.printf("Please enter rainfall for the current day:  ");
            rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
            this.daysCounter  ;
            this.rainEntered = new int[this.daysCounter];
            mainMenu();
          }

          i  ;
        }
        break;
      case 4:
        System.out.printf("n");
        displayHistogram();
        break;
      case 5:
        break;
      case 6:
        break;
      case 7:
        break;
      case 8:
        break;
      default:
        System.out.println("Invalid input, try again");
        mainMenu();
    }
    while (choice != 8)
      ;
  }



  private void createGauge() {
    System.out.printf("nPlease enter the name of the site :");
    this.site = input.nextLine();
    System.out.printf("Please enter the number of days to record :");
    this.days = Integer.parseInt(input.nextLine());
    this.rainRecorded = new int[this.days]; // move the array initialization here
    System.out.printf("Please enter the lattitute :");
    this.lattitude = Float.parseFloat(input.nextLine());
    System.out.printf("Please enter the longitude :");
    this.longitude = Float.parseFloat(input.nextLine());
    mainMenu();
  }

  private void gaugeDetails() {
    if (this.days > 0) {
      System.out.printf("%-9s %-3s %s n", this.message1, this.message6, this.site);
      System.out.printf("%s %-3s % 09.4fn", this.message2, this.message6, this.lattitude);
      System.out.printf("%s %-3s %9.4fn", this.message3, this.message6, this.longitude);
      System.out.printf("%-9s %-3s %-2d%s n", this.message4, this.message6, this.days, this.message5);
      mainMenu();
    } else {
      mainMenu();
    }
  }

  private void displayHistogram() {
    for (int i = 0; i < this.rainEntered.length; i  ) {
      System.out.print(i   " ");
      for (int j = 0; j < this.rainRecorded[i] - 1; j  = 10 ) {
        System.out.print("*");
      }
      System.out.println();
    }
    mainMenu();
  }

  public static void main(String[] args) {
    @SuppressWarnings("unused")
    RainRecording objName;
    objName = new RainRecording();
  }

}
 

Ответ №2:

Итак, ваши коды немного разбросаны по месту, и у меня возникли некоторые проблемы, когда я пытался понять основное намерение, например

 private int[] rainRecorded;
private int[] rainEntered;
 

Я не уверен, каковы намерения для этих двух переменных. Так что в моем примере я отбросил rainEntered на время.

Итак, ваша первая проблема начинается здесь…

 while( i < this.days || this.daysCounter == this.days) {

    if (this.daysCounter == this.days) {

        System.out.printf("Error - system fulln");
        mainMenu();

    }
    if (this.days < 1) {

        mainMenu();

    } else {        
        

        this.rainRecorded = new int[this.days];
        System.out.printf("Please enter rainfall for the current day:  ");
        rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
        this.daysCounter  ;
        this.rainEntered = new int[this.daysCounter];
        mainMenu();
    }
    
    i  ;
}
 

Во-первых, я бы убрал необходимость в двух условиях выхода, так как это затруднит рассуждения о

Далее, проверка достоверности данных должна выполняться вне цикла, и я бы также не стал звонить mainMenu из него, это быстро поставит вас в незнакомое место.

Но моя главная проблема заключается в

 this.rainRecorded = new int[this.days];
System.out.printf("Please enter rainfall for the current day:  ");
rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
this.daysCounter  ;
this.rainEntered = new int[this.daysCounter];
 

Вы продолжаете создавать новые экземпляры обоих this.rainRecorded и this.rainEntered , что означает, что каждый раз, когда выполняется цикл, вы теряете все, что было введено ранее.

Итак, в моей «упрощенной» версии я изменил ее до чего-то вроде…

 if (this.days < 1) {
    System.out.println("Invalid number of days");
    return;
}
if (this.daysCounter == this.days) {
    System.out.printf("Error - system fulln");
    return;
}

while (this.daysCounter < this.days) {
    System.out.printf("Please enter rainfall for the day "   (daysCounter   1)   ":  ");
    rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
    this.daysCounter  ;
}
 

Затем я также упростил рабочий процесс гистограммы, но я все еще пытаюсь разобраться в том, что rainEntered предполагается делать…

 private void displayHistogram() {
    for (int amount : rainRecorded) {
        for (int count = 0; count < amount; count  ) {
            System.out.print("*");
        }
        System.out.println(" "   amount);
    }
}
 

И последнее, что я также сделал, это удалил все вызовы mainMenu и вместо этого полагался на простой do-while цикл для повторной печати меню каждый раз, когда оно возвращалось из Chosen метода

 private void mainMenu() {
    do {
        System.out.println("");
        System.out.println("*** Rain Gauge Menu ***");
        System.out.println("  1: Create rain gauge");
        System.out.println("  2: Display rain gauge details");
        System.out.println("  3: Add daily rainfall measurement");
        System.out.println("  4: Display rainfall histogram");
        System.out.println("  5: Get maximum rainfall");
        System.out.println("  6: Check rainfall is below threshold");
        System.out.println("  7: Display anaylsis");
        System.out.println("  8: Exit");
        System.out.print("Please enter your selection: ");

        Chosen();
    } while (shouldContinue);
}
 

Это упрощает рабочий процесс, так как легче рассуждать о том, где вы находитесь в любой момент выполнения программы, вместо того, чтобы задаваться вопросом, почему, когда при некоторых условиях, когда вы выбрали что-то из меню, вы вместо этого оказываетесь в какой-то другой части программы.

Пример

 import java.util.Scanner;

public class RainRecording {

    private int choice;
    private Scanner input;
    private String site;
    private int days;
    private int daysCounter;
    private int[] rainRecorded;
    //private int[] rainEntered;
    private float lattitude;
    private float longitude;
    private String message1;
    private String message2;
    private String message3;
    private String message4;
    private String message5;
    private String message6;

    private boolean shouldContinue = true;

    // declare name of variable

    public RainRecording() {

        // declare value of variable

        this.message1 = "Site";
        this.message2 = "lattitude";
        this.message3 = "longitude";
        this.message4 = "Window";
        this.message5 = "days";
        this.message6 = ":";
        this.daysCounter = 0;
        this.input = new Scanner(System.in);
        mainMenu();

    }

    private void mainMenu() {
        do {
            System.out.println("");
            System.out.println("*** Rain Gauge Menu ***");
            System.out.println("  1: Create rain gauge");
            System.out.println("  2: Display rain gauge details");
            System.out.println("  3: Add daily rainfall measurement");
            System.out.println("  4: Display rainfall histogram");
            System.out.println("  5: Get maximum rainfall");
            System.out.println("  6: Check rainfall is below threshold");
            System.out.println("  7: Display anaylsis");
            System.out.println("  8: Exit");
            System.out.print("Please enter your selection: ");

            Chosen();
        } while (shouldContinue);
    }

    private void Chosen() {

        this.choice = Integer.parseInt(input.nextLine());
        switch (choice) {
            case 1:
                createGauge();
                break;

            case 2:
                gaugeDetails();
                break;
            case 3:

    if (this.days < 1) {
        System.out.println("Invalid number of days");
        return;
    }
    if (this.daysCounter == this.days) {
        System.out.printf("Error - system fulln");
        return;
    }

    while (this.daysCounter < this.days) {
        System.out.printf("Please enter rainfall for the day "   (daysCounter   1)   ":  ");
        rainRecorded[this.daysCounter] = Integer.parseInt(input.nextLine());
        this.daysCounter  ;
    }
                break;
            case 4:
                System.out.printf("n");
                displayHistogram();
                break;
            case 5:
                break;
            case 6:
                break;
            case 7:
                break;
            case 8: shouldContinue = false;
                break;

            default:
                System.out.println("Invalid input, try again");
        }

    }



    private void createGauge() {
        System.out.printf("nPlease enter the name of the site :");
        this.site = input.nextLine();
        System.out.printf("Please enter the number of days to record :");
        this.days = Integer.parseInt(input.nextLine());
        System.out.printf("Please enter the lattitute :");
        this.lattitude = Float.parseFloat(input.nextLine());
        System.out.printf("Please enter the longitude :");
        this.longitude = Float.parseFloat(input.nextLine());

        if (days > 0) {
            this.rainRecorded = new int[this.days];
        }
    }

    private void gaugeDetails() {

        if (this.days > 0) {

            System.out.printf("%-9s %-3s %s n", this.message1, this.message6, this.site);
            System.out.printf("%s %-3s % 09.4fn", this.message2, this.message6, this.lattitude);
            System.out.printf("%s %-3s %9.4fn", this.message3, this.message6, this.longitude);
            System.out.printf("%-9s %-3s %-2d%s n", this.message4, this.message6, this.days, this.message5);

        }

    }

    private void displayHistogram() {
        for (int amount : rainRecorded) {
            for (int count = 0; count < amount; count  ) {
                System.out.print("*");
            }
            System.out.println(" "   amount);
        }
    }

    public static void main(String[] args) {
        @SuppressWarnings("unused")
        RainRecording objName;
        objName = new RainRecording();
    }
}
 

Теперь, если rainEntered предполагается, что это какой-то сводный массив, где он позволяет записывать несколько дней дождя за разные периоды, вы можете вместо этого рассмотреть возможность использования многомерного массива, чтобы вы могли n использовать периоды, и в каждом периоде могли быть n дни дождя…