【问题标题】:histogram: shortcut for if statements and formatting直方图:if 语句和格式设置的快捷方式
【发布时间】:2017-01-08 21:17:23
【问题描述】:

我的程序从文件中读取任意数量的整数,然后为 1 到 100 之间的所有整数打印直方图条形图。 该代码有效,我已经尝试使用所有可能的格式使其更短,但后来我的代码停止工作。所以这个长版本是目前唯一有效的版本。 所以我的问题只是出于好奇,如果我的 if 语句和直方图的打印有更短的方法。
注意:并非文件中的所有整数都必须在 [1-100] 区间内

    Create an object representing a file
    File file = new File("path");
    Scanner fileScan = new Scanner(file);

    ArrayList<Integer> list = new ArrayList<Integer>();
    int total=0;
    while (fileScan.hasNext()){
        total++;
            list.add(fileScan.nextInt());
    }
    int [] counter = new int [10];
    for(int i=0; i<list.size();i++){
        if (list.get(i) >=1 && list.get(i)<=10){
            counter[0]++;
        }
        if (list.get(i) >10 && list.get(i)<=20){
            counter[1]++;
        }
        if (list.get(i) >20 && list.get(i)<=30){
            counter[2]++;
        }
        if (list.get(i) >30 && list.get(i)<=40){
            counter[3]++;
        }
        if (list.get(i) >40 && list.get(i)<=50){
            counter[4]++;
        }
        if (list.get(i) >50 && list.get(i)<=60){
            counter[5]++;
        }
        if (list.get(i) >60 && list.get(i)<=70){
            counter[6]++;
        }
        if (list.get(i) >70 && list.get(i)<=80){
            counter[7]++;
        }
        if (list.get(i) >80 && list.get(i)<=90){
            counter[8]++;
        }
        if (list.get(i) >90 && list.get(i)<=100){
            counter[9]++;
        }
    }
    int valueTotal=0;
    for (int j=0; j<counter.length; j++){
        valueTotal += counter[j];
    }
    System.out.print("Reading integers from file: "+file);
    System.out.print("\nNumber of integers in the interval [1,100]: "+valueTotal);
    System.out.print("\nOthers: "+(total-valueTotal));
    System.out.print("\nHistogram\n");  
    System.out.print("1 - 10  | ");
    display(counter[0]);
    System.out.print("\n11 - 20 | ");
    display(counter[1]);
    System.out.print("\n21 - 30 | ");
    display(counter[2]);
    System.out.print("\n31 - 40 | ");
    display(counter[3]);
    System.out.print("\n41 - 50 | ");
    display(counter[4]);
    System.out.print("\n51 - 60 | ");
    display(counter[5]);
    System.out.print("\n61 - 70 | ");
    display(counter[6]);
    System.out.print("\n71 - 80 | ");
    display(counter[7]);
    System.out.print("\n81 - 90 | ");
    display(counter[8]);
    System.out.print("\n91 - 100| ");
    display(counter[9]);
    }
    public static void display(int n){
    for (int i=0; i<n; i++){
        System.out.print("*");
    }
    }
}

我的输出:

   Reading integers from file: ....txt
   Number of integers in the interval [1,100]: 18
   Others: 4
   Histogram
   1 - 10  | ******
   11 - 20 | *
   21 - 30 | ***
   31 - 40 | 
   41 - 50 | *
   51 - 60 | *
   61 - 70 | *
   71 - 80 | ***
   81 - 90 | *
   91 - 100| *

【问题讨论】:

  • 您必须始终在两端为超出范围的值设置 bin(counter 元素),除非您可以保证 bin 计算不会产生超出范围的 bin 编号。

标签: java format histogram


【解决方案1】:

当您收集大小为 10 的段中的值时,您可以使用/(整数除法)来计算索引:

for (int i=0; i<list.size(); i++) {
    int value = Math.min(list.get(i), 100);
    int index = value / 10 - 1;
    counter[index]++;
}

【讨论】:

  • 在线程 "main" java.lang.ArrayIndexOutOfBoundsException: 13 中生成异常 Exception: 13
  • 只有当你输入的值大于100时才可以轻松处理,并且必须像@Hovercraft Full Of Eels例子那样调整索引。此外,最好提前初始化 counter 数组。
  • 哦,没错。我没有在我的帖子中说明这一点。因为程序读取任意数量的整数,并计算介于 1 - 100 之间的整数,并且还计算不在此 Intervall 中的整数。您只能在输出中看到它。但我会马上编辑。
【解决方案2】:

是的,counter[(list.get(i) - 1) / 10]++; 或类似的东西应该能够替换所有这些 if 语句。

编辑:鉴于您更改的要求,您需要首先测试索引是否超出范围:

int index = (list.get(i) - 1 ) / 10;
if (index >= 0 || index < counter.length) {
    counter[index]++;
} else {
    // not sure if you need to do something for index out of bounds
}

【讨论】:

  • 这也给了我一个异常 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 13 正如 hotzst 已经提到的,我忘了写程序也计算 Intervall [1, 100 ]
  • @Bruthzilla:那么您最好在将其用作索引之前对其进行测试。
【解决方案3】:

counter[(list.get(i) - 1) / 10]++; 似乎是最简洁的。您还可以在 for 循环中使用 switch statement 来摆脱 if 并将所有内容放在同一个代码块中。此外,将元素存储在第 i 个索引处可以节省大量重复的 getting

编辑:原始代码与 Java 语法不一致。这是更新的版本。 switch 里面的表达式是关键:

for(int i = 0; i < lst.size(); i++){
  int x = lst.get(i);
  switch((x-1)/10){
    case 1: counter[0]++;
    case 2: counter[1]++;
    case 3: counter[2]++;
    case 4: counter[3]++;
    case 5: counter[4]++;
    case 6: counter[5]++;
    case 7: counter[6]++;
    case 8: counter[7]++;
    case 9: counter[8]++;
  }
}

【讨论】:

  • 那是有效的 Java 吗?你确定吗?你测试过吗?
猜你喜欢
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多