使用星号的Java直方图

时间:2014-07-22 03:16:51

标签: java

我正在尝试创建一个利用应用程序来运行程序的直方图类。

 public class Histogram
{
   String name;
   int max;


   public Histogram (String name, int max)
   {
      this.name = name;
      this.max = max;
   }

   int[] count = new int[max+1];

   public void add(int numbers) 
   {
    // Handles out of bounds case
    if (numbers < 0 || numbers > max)
        return;

    count[numbers]++;
   }

   public String toString()
   {
      String result = name + "\n";
      for (int index = 0; index < count.length; index++)
      {
      result = result + count[index] + ": ";
         for (int indexStar = 0; indexStar < count[index]; indexStar++)
            result = result + "*";
         result = result + "\n";
         }
         return result;
   }
}

我的申请:

public class HistogramDataCollector
{
   public static void main (String[] args)
   {
      Histogram h = new Histogram ("Favorite Number Survey", 11);

      h.add(1); h.add(0); h.add(9); h.add(7); h.add(7);
      h.add(3); h.add(4); h.add(6); h.add(5); h.add(2);
      h.add(2); h.add(8);

      System.out.println(h);
   }
}

我正在努力弄清楚如何添加int数字以获得它们出现的频率来制定用星号创建的直方图。 谢谢!

1 个答案:

答案 0 :(得分:0)

您需要做的第一件事是摆脱课堂上所有方法之外的无关for循环代码。这不允许您的代码编译。但是,一旦删除该代码,此类应该直接运行。您也可以删除numbers数组,因为它没有在您的类中使用。只需使用count变量,您就会明白为什么。

另外需要注意的是,您需要更改构造函数和变量定义,使它们看起来像这样:

String name;
int max;
int[] count;

public Histogram(String name, int max) 
{
   this.name = name;
   this.max = max;
   this.count = new int[max+1];  
}

原因是因为当您创建此类的对象时,max被假定为 0 。因此,这将声明一个大小 1 的数组,并且当您在构造函数中读入max变量时它不会更改。因此,您需要将其保留为未分配,然后在构造函数中分配数组


正如您所提到的,您对如何从此直方图类中获取其出现频率感到困惑。记住直方图的定义。直方图 是您在数据中看到的数字的频率。您班级中的count数组将自动存储频率或您在数据集中看到该特定数字的次数。您使用add()方法,此方法的输入是您要观察到的直方图中的数字。

作为直方图如何工作的示例,如果count[0] = 1, count[1] = 2, count[2] = 4,则表示您看到0的次数是1次,1 2次,{{1您的数据集中有4次。因此,您只需迭代计数数组的每个元素以检索每个数字的频率。根据您在测试器类中的上述示例,在调用各种添加方法后,每个数字的频率计数将为:2

count[0] = 1, count[1] = 1, count[2] = 2, count[3] = 1, count[4] = 1, count[5] = 1, count[6] = 1, count[7] = 2, count[8] = 1, count[9] = 1, count[10] = 0中的每个位置您看到该数字的次数。因此,对于count方法,add()是您看到的数字。因此,您可以访问属于该数字的特定插槽,并将计数增加1.例如,执行numbers将等同于h.add(0);,这与count[0]++;相同。访问广告位count[0] = count[0] + 1;,并增加1.我们已经看到了这个0时间。对于1的后续调用,我们会看到该特定数字是额外的时间。

但是,您的添加方法不会执行错误检查。具体来说,如果您指定的数字小于0或大于h.add,当您尝试递增直方图的区间时,将获得max。因此,如果发生这种情况,我建议您只是从方法返回而不做任何事情。换句话说:

OutOfBoundsException

在您的班级定义中,执行public void add(int numbers) { // Handles out of bounds case if (numbers < 0 || numbers > max) return; count[numbers]++; } 会自动将此数组中的所有元素分配给0. int count[] = new int[max+1];将是您在数据集中看到的最高数字。确保将max添加到0索引的帐户中,这就是它为1个广告位分配的原因。我们这样做是为了确保我们能够记录数据集中所见的每个可能数字的数字频率。当您从此类创建对象时,所有这些bin都将重置为0,因此您可以立即开始使用该对象。


我想要注意的一件事是你说你想通过显示星号来表示bin计数来实现这个直方图。因此,您需要将max+1方法修改为:

toString()

上面的代码将做的是对于直方图中的每个bin,它将显示数字的频率计数,在后面放置一个冒号,一个空格,然后放置与频率一样多的星号。那个特定的号码。因此,如果你考虑我的第一个例子,你应该看到:

public String toString()
{
   String result = name + "\n";
   for (int index = 0; index < count.length; index++) {
       result = result + index + ": "; // New
       for (int indexStar = 0; indexStar < count[index]; indexStar++) // New
           result = result + "*"; // New
       result = result + "\n"; // New
   }
   return result;
}

请注意,我只是显示频率计数的样子。我还没有正确地创建这个类的对象,所以直方图的名称是未定义的。但是,这是直方图频率计数应该看到的。


希望这能解决你的问题!