计算ASCII字符频率时的ArrayIndexOutOfBoundsException

时间:2014-03-05 09:01:05

标签: java arrays for-loop ascii indexoutofboundsexception

我正在尝试从转换为字符数组的String输入中计算ASCII字符的频率。

我尝试从this线程实现接受的答案,以及我的代码,以便在3列表格中打印结果。

package com.mypackage.mp;

import java.util.*;

public class AsciiCounter {

    public static void displayAsciiOccurrence(String inputWords) {
        int[] iaCount = new int[256]; //this
        char[] caInputWords = inputWords.toCharArray();

        int i = 0;
        for(i = 0; i < caInputWords.length; i++) {
            iaCount[caInputWords[i]]++;
        }

        // Print table
        System.out.println("\nDEC\tASCII\tFREQ");

        for(int ctr = 0; ctr < 256; ctr++) {
            System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[caInputWords[i]]); //this
        }
    }

    public static void main(String[] args) {
        String inputWords = null;
        Scanner scn = new Scanner(System.in);

        System.out.print("Enter words: ");
        inputWords = scn.nextLine();

        displayAsciiOccurrence(inputWords); //this

        scn.close();
    }
}

但是,它返回ArrayIndexOutOfBoundsException。我想要的输出应该是:

Enter words: AA bC! d

DEC     ASCII       FREQ
0
..      ..          ..
32                  2
33      !           1
..      ..          ..
65      A           2
66      B           0
67      C           1
..
98      b           1
99      c           0
100     d           1
..
255

..适用于介于两者之间的任何内容,必须将0作为频率打印。)

堆栈追踪:

  

线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:8     在   com.mypackage.mp.AsciiCounter.displayAsciiOccurrence(AsciiCounter.java:20)     在   com.mypackage.mp.AsciiCounter.main(AsciiCounter.java:31)

4 个答案:

答案 0 :(得分:3)

错误出现在您的打印循环中:

System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[caInputWords[i]]);

由于i自第一个循环后没有变化,此时它等于caInputWords.length

我想你的意思是:

System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);

作为旁注,您可能不希望自己打印所有ASCII字符。其中一些不代表可打印的字符或是空格。解决此问题的一个简单方法是在打印前检查iaCount[ctr] > 0,这样您就只能打印字符串中的字符。

答案 1 :(得分:2)

你的第二个循环中有问题:

    for(int ctr = 0; ctr < 256; ctr++) {
        System.out.println(ctr +"\t" + (char) (ctr) + "\t" 
            + iaCount[caInputWords[i]] // HERE
        );
    }

你的意思是iaCount[ctr]!当您进入此循环时,使用i为256,因为它已被前一个循环设置为此值。由于iaCount数组只有256个字符长,因此该索引超出范围。

另外,如果输入非ASCII字符,则无法检查会发生什么。

要避免此类错误,请将您的第一个for循环更改为:

for(int i = 0; i < 256; i++)

在第一个循环中执行此操作会显示第二个中不存在i

答案 2 :(得分:1)

该行可以抛出异常。

System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[caInputWords[i]]); 将其更改为

 for(int ctr = 0; ctr < 256; ctr++) {
            System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);
        }

答案 3 :(得分:1)

i变量尚未重置。但是在频率计算之后你根本不需要使用变量i。你需要使用ctr来表示所有角色的频率。

    for(int ctr = 0; ctr < 256; ctr++) {
        System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);
    }