【问题标题】:ArrayIndexOutOfBoundsException while counting ASCII character frequency计算 ASCII 字符频率时出现 ArrayIndexOutOfBoundsException
【发布时间】:2014-04-07 05:26:27
【问题描述】:

我正在尝试从转换为字符数组的字符串输入中计算 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)

【问题讨论】:

  • 你能在你得到那个异常的那一行添加吗?谢谢。
  • 您能否编辑您的问题以添加完整的堆栈跟踪?
  • 请注意,.toCharArray() 基本上会“复制”字符串中的所有字符;您可能想改用String.charAt()
  • 已编辑问题以包含堆栈跟踪。感谢您的帮助。

标签: java arrays for-loop ascii indexoutofboundsexception


【解决方案1】:

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

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] &gt; 0,以便您只打印字符串中开头的字符。

【讨论】:

  • 感谢您的建议。机器问题要求它打印整个 ASCII 表,包括不可打印的字符和空格。如果需求需要它,您的提示将很有用。赞成。
【解决方案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 在第二个循环中不存在。

【讨论】:

    【解决方案3】:

    该行可能会引发异常。

    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]);
            }
    

    【讨论】:

      【解决方案4】:

      i 变量尚未重置。但是在频率计算之后你根本不需要使用变量 i 。您需要使用 ctr 来获取所有字符的频率。

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

      【讨论】:

      • 谢谢。我还使用了 iaCount.length 而不是硬编码 256。标记为已接受的答案。
      猜你喜欢
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多