Java – 竖直柱状图故障排除:最大值损坏?

huangapple go评论78阅读模式
英文:

Java - Vertical Histogram troubleshoot: broken max value?

问题

import java.util.Scanner;

public class Histogram
{
    public static void main(String[] args) {
        //variables
        Scanner keyboard = new Scanner(System.in);
        int numInputs = 1, temp, maximum = 0;
        int[] numbers = new int[31];
        int[] count = new int[31];
        boolean success = false;

        //start of program
        System.out.println("How many input values [max:30]?");

        //while no valid input
        while (!success) {
            try {
                numInputs = keyboard.nextInt(); //get a number
                numInputChecker(numInputs);     //is it valid?
                success = true;                 //ok

            } catch (Exception e)                 //else get a new number
            {
                keyboard.nextLine();
                System.out.println("Whole numbers 1 through 30 only, please.");

            }
        }
        //reset the loop checker
        success = false;

        //read numbers to fill that array
        System.out.println("Enter " + numInputs + " numbers.");

        for (int i = 0; i < numInputs; i++)     //from 0 to max number
        {
            while (!success)                   //while no valid number
            {
                try {
                    numbers[i] = keyboard.nextInt();    //fill the current cell with a number
                    numberChecker(numbers[i]);          //is it valid?
                    success = true;                     //ok
                } catch (Exception e)                     //else get a new number
                {
                    keyboard.nextLine();
                    System.out.println("Whole numbers 0 through 9 only, please.");
                }
            }
            success = false;
        }

        //for cells not used
        for (int i = numInputs; i < numbers.length; i++) {
            numbers[i] = 10;    //fill with garbage data (to prevent false positive 0s)
        }

        //take the input and count each use of element
        for (int i : numbers)  //for 0 to max number
        {
            temp = i;  //get the current value of the cell
            count[temp]++;      //add the use of that value to a new array's cell
        }

        System.out.println("Number Occurrence");

        for (int i = 0; i < count.length; i++)   //from 0 to 9 (expected)
        {
            if ((count[i] > 0) && (count[i] <= 9))  //if cell not empty and has valid data
            {
                System.out.println(i + " " + count[i]);  //print the current cell and how many times it was used
            }
        }
        System.out.println();   //spacer

        //histogram segment

        //find the highest-used number
        for (int i : count)             //for each number
        {
            if(i > maximum)             //if greater than the current max
            {
                maximum = i;            //set to max
            }
        }

        System.out.println("========= Vertical Bar ========");
        for (int i = maximum; i > 0; i--)        //max through 1
        {
            if ((count[i] > 0) && (count[i] <=9))   //if has valid data
            {
                System.out.print((i) + "\t | ");      // print the number and a nice line for readability

                for (int j = 0; j < count.length; j++)      //for the number of times that number was used
                {
                    if ((count[j] > 0) && (count[j] <=9))   //if has valid data
                    {
                        if (count[j] >= i)                  //if that number the max
                        {
                            System.out.print("* ");            //print an asterisk
                        }
                        else
                            {
                                System.out.print("  ");     //"skip" and keep alignment
                            }
                    }
                }
                System.out.println();                   //make a new line
            }
        }

        System.out.println("===============================");  //footer
        System.out.println("| No | 0 1 2 3 4 5 6 7 8 9");
        System.out.println("===============================");
    }

    static void numInputChecker(int integer) throws Exception
    {
        if ((integer < 1) || (integer > 30))    //if 0 or negative, or if 31+
        {
            throw new Exception();              //say no
        }
    }

    static void numberChecker(int integer) throws Exception
    {
        if ((integer < 0) || (integer > 9)) //if negative or 10+
        {
            throw new Exception();          //say no
        }
    }
}
英文:

So after much trial and error I converted my horizontal histogram to a vertical one, at least partially.

It seems that instead of reading the highest number of times used, it simply reads the value of the highest-used number:

How many input values [max:30]?
5
Enter 5 numbers.
2
1
2
0
2
Number Occurrence
0 1
1 1
2 3
========= Vertical Bar ========
2	 |     * 
1	 | * * * 
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

leaves out the max height of 3 and removes an asterisk

How many input values [max:30]?
1
Enter 1 numbers.
5
Number Occurrence
5 1
========= Vertical Bar ========
5	 |   
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

does not print

5
Enter 5 numbers.
3
3
3
3
3
Number Occurrence
3 5
========= Vertical Bar ========
3	 | * 
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

prints the wrong max, the wrong number of asterisks, and in the wrong spot

How many input values [max:30]?
10
Enter 10 numbers.
5
4
3
2
1
1
2
3
4
5
Number Occurrence
1 2
2 2
3 2
4 2
5 2
========= Vertical Bar ========
5	 |           
4	 |           
3	 |           
2	 | * * * * * 
1	 | * * * * * 
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

adds whitespace for 5-3

10
Enter 10 numbers.
2
2
3
3
3
4
4
4
4
1
Number Occurrence
1 1
2 2
3 3
4 4
========= Vertical Bar ========
4	 |       * 
3	 |     * * 
2	 |   * * * 
1	 | * * * * 
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

works as intended although not by design


public class Histogram
{
public static void main(String[] args) {
//variables
Scanner keyboard = new Scanner(System.in);
int numInputs = 1, temp, maximum = 0;
int[] numbers = new int[31];
int[] count = new int[31];
boolean success = false;
//start of program
System.out.println(&quot;How many input values [max:30]?&quot;);
//while no valid input
while (!success) {
try {
numInputs = keyboard.nextInt(); //get a number
numInputChecker(numInputs);     //is it valid?
success = true;                 //ok
} catch (Exception e)                 //else get a new number
{
keyboard.nextLine();
System.out.println(&quot;Whole numbers 1 through 30 only, please.&quot;);
}
}
//reset the loop checker
success = false;
//read numbers to fill that array
System.out.println(&quot;Enter &quot; + numInputs + &quot; numbers.&quot;);
for (int i = 0; i &lt; numInputs; i++)     //from 0 to max number
{
while (!success)                   //while no valid number
{
try {
numbers[i] = keyboard.nextInt();    //fill the current cell with a number
numberChecker(numbers[i]);          //is it valid?
success = true;                     //ok
} catch (Exception e)                     //else get a new number
{
keyboard.nextLine();
System.out.println(&quot;Whole numbers 0 through 9 only, please.&quot;);
}
}
success = false;
}
//for cells not used
for (int i = numInputs; i &lt; numbers.length; i++) {
numbers[i] = 10;    //fill with garbage data (to prevent false positive 0s)
}
//take the input and count each use of element
for (int i : numbers)  //for 0 to max number
{
temp = i;  //get the current value of the cell
count[temp]++;      //add the use of that value to a new array&#39;s cell
}
System.out.println(&quot;Number Occurrence&quot;);
for (int i = 0; i &lt; count.length; i++)   //from 0 to 9 (expected)
{
if ((count[i] &gt; 0) &amp;&amp; (count[i] &lt;= 9))  //if cell not empty and has valid data
{
System.out.println(i + &quot; &quot; + count[i]);  //print the current cell and how many times it was used
}
}
System.out.println();   //spacer
//histogram segment
//find the highest-used number
for (int i : count)             //for each number
{
if(i &gt; maximum)             //if greater than the current max
{
maximum = i;            //set to max
}
}
System.out.println(&quot;========= Vertical Bar ========&quot;);
for (int i = maximum; i &gt; 0; i--)        //max through 1
{
if ((count[i] &gt; 0) &amp;&amp; (count[i] &lt;=9))   //if has valid data
{
System.out.print((i) + &quot;\t | &quot;);      // print the number and a nice line for readability
for (int j = 0; j &lt; count.length; j++)      //for the number of times that number was used
{
if ((count[j] &gt; 0) &amp;&amp; (count[j] &lt;=9))   //if has valid data
{
if (count[j] &gt;= i)                  //if that number the max
{
System.out.print(&quot;* &quot;);            //print an asterisk
}
else
{
System.out.print(&quot;  &quot;);     //&quot;skip&quot; and keep alignment
}
}
}
System.out.println();                   //make a new line
}
}
System.out.println(&quot;===============================&quot;);  //footer
System.out.println(&quot;| No | 0 1 2 3 4 5 6 7 8 9&quot;);
System.out.println(&quot;===============================&quot;);
}
static void numInputChecker(int integer) throws Exception
{
if ((integer &lt; 1) || (integer &gt; 30))    //if 0 or negative, or if 31+
{
throw new Exception();              //say no
}
}
static void numberChecker(int integer) throws Exception
{
if ((integer &lt; 0) || (integer &gt; 9)) //if negative or 10+
{
throw new Exception();          //say no
}
}
}
</details>
# 答案1
**得分**: 1
你的问题在于你在星号输出逻辑中有太多的`if`块。根据数据,在某些水平位置上你决定不打印任何内容,但实际上你想要做的是在每个水平位置上打印两个字符(要么是一个空格加一个星号,要么是两个空格),而不管在该位置是否看到任何数字。因此,如果你去掉所有的`if`块,只保留一个`if`块,你的打印代码会变得更简单,并且会得到正确的结果:
```java
System.out.println("========= Vertical Bar ========");
// 对于每个计数,从最大值开始...
for (int i = maximum; i > 0; i--) {
System.out.print((i) + "\t | ");
// 对于从0到最大数字的每个数字
for (int j = 0; j < count.length; j++) {
// 如果在此水平位置的计数大于或等于垂直计数(我们所在的行号),则打印一个星号,否则打印一个空格。
if (count[j] >= i) {
System.out.print("* ");
} else {
System.out.print("  ");
}
}
System.out.println();
}
System.out.println("==============================");
System.out.println("| No | 0 1 2 3 4 5 6 7 8 9");
System.out.println("==============================");

以下是我用于测试的一个相当复杂的结果:

输入:

int[] numbers = { 1, 2, 3, 4, 5, 1, 1, 3, 3, 5, 5, 3, 3, 5, 5, 7 };

结果:

Number Occurrence
1 3
2 1
3 5
4 1
5 5
7 1
========= Vertical Bar ========
5	 |       *   *                                                   
4	 |       *   *                                                   
3	 |   *   *   *                                                   
2	 |   *   *   *                                                   
1	 |   * * * * *   *                                               
==============================
| No | 0 1 2 3 4 5 6 7 8 9
==============================
英文:

Your problem is that you have too many if blocks in your asterisks output logic. You're deciding not to print anything at some horizontal positions based on the data, when what you really want to do is print two characters (either a space plus an asterisk or two spaces) at each position horizontally, regardless of if you saw any numbers at that position. So your print code gets simpler and does the right thing if you take out all but one if block to arrive at this:

System.out.println(&quot;========= Vertical Bar ========&quot;);
// for each count, starting from the max...
for (int i = maximum; i &gt; 0; i--) 
{
System.out.print((i) + &quot;\t | &quot;);          
// for each number from 0 to the largest number we saw
for (int j = 0; j &lt; count.length; j++) 
{
// If the count at this position horizontally is greater than or
// equal to the count vertically (the line number we&#39;re on), then
// print an asterisk, else print a blank space.
if (count[j] &gt;= i).   
{                    
System.out.print(&quot;* &quot;);           
}
else
{
System.out.print(&quot;  &quot;);           
}
}
System.out.println();                  
}
System.out.println(&quot;===============================&quot;);
System.out.println(&quot;| No | 0 1 2 3 4 5 6 7 8 9&quot;);
System.out.println(&quot;===============================&quot;);

Here's a pretty complicated result that I was using for testing:

Input:

int[] numbers = { 1, 2, 3, 4, 5, 1, 1, 3, 3, 5, 5, 3, 3, 5, 5, 7 };

Result:

Number Occurrence
1 3
2 1
3 5
4 1
5 5
7 1
========= Vertical Bar ========
5	 |       *   *                                                   
4	 |       *   *                                                   
3	 |   *   *   *                                                   
2	 |   *   *   *                                                   
1	 |   * * * * *   *                                               
===============================
| No | 0 1 2 3 4 5 6 7 8 9
===============================

答案2

得分: 0

import java.util.Scanner;

public class Histogram
{
    public static void main(String[] args)
    {
        //variables
        Scanner keyboard = new Scanner(System.in);
        int numInputs = 1, temp, maximum = 0;
        int[] numbers = new int[31];
        int[] count = new int[31];
        boolean success = false;

        //start of program
        System.out.println("How many input values [max:30]?");

        //while no valid input
        while (!success)
        {
            try
            {
                numInputs = keyboard.nextInt(); //get a number
                numInputChecker(numInputs);     //is it valid?
                success = true;                 //ok

            } catch (Exception e)                 //else get a new number
            {
                keyboard.nextLine();
                System.out.println("Whole numbers 1 through 30 only, please.");

            }
        }
        //reset the loop checker
        success = false;

        //read numbers to fill that array
        System.out.println("Enter " + numInputs + " numbers.");

        for (int i = 0; i < numInputs; i++)     //from 0 to max number
        {
            while (!success)                   //while no valid number
            {
                try
                {
                    numbers[i] = keyboard.nextInt();    //fill the current cell with a number
                    numberChecker(numbers[i]);          //is it valid?
                    success = true;                     //ok
                } catch (Exception e)                   //else get a new number
                {
                    keyboard.nextLine();
                    System.out.println("Whole numbers 0 through 9 only, please.");
                }
            }
            success = false;
        }

        //for cells not used
        for (int i = numInputs; i < numbers.length; i++)
        {
            numbers[i] = -1;    //fill with garbage data (to prevent false positive 0s)
        }

        //take the input and count each use of element
        for (int i : numbers)  //for 0 to max number
        {
            if (i != -1)       //if valid data
            {
                temp = i;           //get the current value of the cell
                count[temp]++;      //add the use of that value to a new array's cell
            }

        }

        System.out.println("Number Occurrence");

        for (int i = 0; i < count.length; i++)   //from 0 to 9 (expected)
        {
            if (count[i] > 0)  //if cell has valid data
            {
                System.out.println(i + " " + count[i]);  //print the current cell and how many times it was used
            }
        }
        System.out.println();   //spacer

        //histogram segment

        //find the highest-used number
        for (int k : count)              //for 0 to 9
        {
            if (k > maximum)             //if greater than the current max
            {
                maximum = k;             //set to max
            }
        }

        System.out.println("========= Vertical Bar ========");

        for (int i = maximum; i > 0; i--) // from max to 1
        {
            System.out.print((i) + "\t | ");    //print the number and a spacer for visibility


            for (int j = 0; j < count.length; j++)   // from 0 to max
            {

                    if (count[j] >= i)                    // If the count at this position horizontally is greater than or
                                                          // equal to the count vertically (the line number we're on)
                    {
                        System.out.print("* ");           //print an asterisk
                    }
                    else
                        {
                            System.out.print("  ");       //else print a blank
                        }
            }
            System.out.println();                         //spacer
        }
        //footer
        System.out.println("===============================");
        System.out.println("| No | 0 1 2 3 4 5 6 7 8 9");
        System.out.println("===============================");
        }

    static void numInputChecker(int integer) throws Exception
    {
        if ((integer < 1) || (integer > 30))    //if 0 or negative, or if 31+
        {
            throw new Exception();              //say no
        }
    }

    static void numberChecker(int integer) throws Exception
    {
        if ((integer < 0) || (integer > 9)) //if negative or 10+
        {
            throw new Exception();          //say no
        }
    }

}
英文:

public class Histogram
{
public static void main(String[] args)
{
//variables
Scanner keyboard = new Scanner(System.in);
int numInputs = 1, temp, maximum = 0;
int[] numbers = new int[31];
int[] count = new int[31];
boolean success = false;
//start of program
System.out.println(&quot;How many input values [max:30]?&quot;);
//while no valid input
while (!success)
{
try
{
numInputs = keyboard.nextInt(); //get a number
numInputChecker(numInputs);     //is it valid?
success = true;                 //ok
} catch (Exception e)                 //else get a new number
{
keyboard.nextLine();
System.out.println(&quot;Whole numbers 1 through 30 only, please.&quot;);
}
}
//reset the loop checker
success = false;
//read numbers to fill that array
System.out.println(&quot;Enter &quot; + numInputs + &quot; numbers.&quot;);
for (int i = 0; i &lt; numInputs; i++)     //from 0 to max number
{
while (!success)                   //while no valid number
{
try
{
numbers[i] = keyboard.nextInt();    //fill the current cell with a number
numberChecker(numbers[i]);          //is it valid?
success = true;                     //ok
} catch (Exception e)                   //else get a new number
{
keyboard.nextLine();
System.out.println(&quot;Whole numbers 0 through 9 only, please.&quot;);
}
}
success = false;
}
//for cells not used
for (int i = numInputs; i &lt; numbers.length; i++)
{
numbers[i] = -1;    //fill with garbage data (to prevent false positive 0s)
}
//take the input and count each use of element
for (int i : numbers)  //for 0 to max number
{
if (i != -1)       //if valid data
{
temp = i;           //get the current value of the cell
count[temp]++;      //add the use of that value to a new array&#39;s cell
}
}
System.out.println(&quot;Number Occurrence&quot;);
for (int i = 0; i &lt; count.length; i++)   //from 0 to 9 (expected)
{
if (count[i] &gt; 0)  //if cell has valid data
{
System.out.println(i + &quot; &quot; + count[i]);  //print the current cell and how many times it was used
}
}
System.out.println();   //spacer
//histogram segment
//find the highest-used number
for (int k : count)              //for 0 to 9
{
if (k &gt; maximum)             //if greater than the current max
{
maximum = k;             //set to max
}
}
System.out.println(&quot;========= Vertical Bar ========&quot;);
for (int i = maximum; i &gt; 0; i--) // from max to 1
{
System.out.print((i) + &quot;\t | &quot;);    //print the number and a spacer for visibility
for (int j = 0; j &lt; count.length; j++)   // from 0 to max
{
if (count[j] &gt;= i)                    // If the count at this position horizontally is greater than or
// equal to the count vertically (the line number we&#39;re on)
{
System.out.print(&quot;* &quot;);           //print an asterisk
}
else
{
System.out.print(&quot;  &quot;);       //else print a blank
}
}
System.out.println();                         //spacer
}
//footer
System.out.println(&quot;===============================&quot;);
System.out.println(&quot;| No | 0 1 2 3 4 5 6 7 8 9&quot;);
System.out.println(&quot;===============================&quot;);
}
static void numInputChecker(int integer) throws Exception
{
if ((integer &lt; 1) || (integer &gt; 30))    //if 0 or negative, or if 31+
{
throw new Exception();              //say no
}
}
static void numberChecker(int integer) throws Exception
{
if ((integer &lt; 0) || (integer &gt; 9)) //if negative or 10+
{
throw new Exception();          //say no
}
}
}

huangapple
  • 本文由 发表于 2020年9月12日 10:39:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63856332.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定