不正确的num histgram

时间:2016-09-07 10:01:02

标签: histogram

我试图制作一个toString方法,打印出一个直方图,显示字母表中每个字符的使用频率。最常见的角色必须是60#长,其余的角色然后缩放以匹配。

我的问题是制作方程式,将其余字母缩放到直方图的正确长度。我目前的等式是(myArray [i] / max)* 60,但我得到了非常奇怪的结果。

如果我把“你好世界”放进去分析,L将是最常见的出现信,见过3次。所以L应该有60#直方图,h应该有20,o应该有40等。相反我得到的结果像d:10 e:10 h:10 l:360 o:20 r:10 w:10

对不起,现在这是多么草率,我只想弄清楚最新情况

public class LetterCounter

    private static int[] alphabetArray; 
    private static String input; 

    /**
     * Constructor for objects of class LetterCounter
     */
    public LetterCounter()
    {
        alphabetArray = new int[26]; 
    }

    public void countLetters(String input) {
        this.input = input; 
        this.input.toLowerCase(); 
        //String s= input; 
        //s.toLowerCase();
        for ( int i = 0; i < input.length(); i++ ) {
            char ch=  input.charAt(i);
            if (ch >= 97 && ch <= 122){
                alphabetArray[ch-'a']++;
            }
        }

    }

    public void getTotalCount() {
        for (int i = 0; i < alphabetArray.length; i++) {
            if(alphabetArray[i]>=0){
                char ch = (char) (i+97); 
                System.out.println(ch +"  : "+alphabetArray[i]);   
            }         
        }
    }

    public void reset() {
        for (int i =0; i<alphabetArray.length; i++) {
            if(alphabetArray[i]>=0){
                alphabetArray[i]=0; 
                char ch = (char) (i+97); 
                System.out.println(ch +"  : "+alphabetArray[i]);   
            }    
        }
    }

    public String toString() {

        String s = ""; 
        int max = alphabetArray[0]; 
        int markCounter = 0; 

        for(int i =0; i<alphabetArray.length; i++) {
            //finds the largest number of occurences for any letter in the string
            if(alphabetArray[i] > max) {
                max = alphabetArray[i];
            }
        }

        for(int i =0; i<alphabetArray.length; i++) {
            //trying to scale the rest of the characters down here
            if(alphabetArray[i] > 0) {
                markCounter = (alphabetArray[i] / max) * 60; 
                char ch = (char) (i+97); 
                System.out.println(ch +"  : "+alphabetArray[i] + markCounter);
            }
        }

        for (int i = 0; i < alphabetArray.length; i++) {
            //prints the whole alphabet, total number of occurences for all chars
            if(alphabetArray[i]>=0){
                char ch = (char) (i+97); 
                System.out.println(ch +"  : "+alphabetArray[i]);   
            }  
        }
        return s; 
    }
}

2 个答案:

答案 0 :(得分:0)

您的代码存在许多问题,但请逐一进行。

首先,您的打印声明只是误导。将其更改为

System.out.println(ch +"  : "+alphabetArray[i] + " " + markCounter);

你会看到

d  : 1 0
e  : 1 0
h  : 1 0
l  : 3 60
o  : 2 0
r  : 1 0
w  : 1 0

如您所见:计数器是正确的(1,1,1,3,2,1,1)。但你的缩放不起作用:

1 / 3 --> 0 ... and 0 * 3 ... is still 0
3 / 3 --> 1     and 1 * 3 ... is 60

但当然,当你不打印1到0和3到60之间的空格时。

因此,要获得正确的缩放比例,只需更改为:

markCounter = alphabetArray[i] * 60 / max; 

其他值得一提的事情:

  1. 覆盖 toString()。然后你应该把@Override放在那个方法的前面
  2. toLowerCase()以小写字母返回一个新字符串;只是调用它而不将结果推回到你的字符串中...只是扔掉了“下壳”。
  3. toString()不应该打印到控制台。整个想法是将所有信息放入您返回的字符串中。换句话说:最后你会做一些System.out.println(someLetterCounter.toString()
  4. 您的代码非常低级。你不用for(int)迭代数组,你可以做(​​int letter:alphabetArray)而不是
  5. 您可能想了解Map。你看,如果你要使用Map<Character, Integer>,其中地图键代表不同的字符,而地图值代表每个字符的计数器......好吧,你可以抛弃你的大部分代码;并提出一个只需几行代码的解决方案!
  6. (并且认真地说:因为所有这些问题,调试代码实际上要比它需要的更难)

答案 1 :(得分:0)

countLetters似乎有一些问题。您只需调用

即可将String转换为小写
this.input.toLowerCase();

因为String在java中是不可变的。你必须像下面这样分配:

this.input = input.toLowerCase();

另一个问题是你使用input变量来自参数而不是this.input,它具有小写字符串。您可以通过这种方式创建工作countLetters方法:

public void countLetters(String input) {
    this.input = input.toLowerCase(); 
    for ( int i = 0; i < this.input.length(); i++ ) {
        char ch=  this.input.charAt(i);
        if (ch >= 97 && ch <= 122) {
            alphabetArray[ch-'a']++;
        }
    }
}