I am trying to count the frequency of ASCII characters from a String input that was converted to a character array.
I tried to implement the accepted answer from this thread, along with my code to print the results in a 3-column table.
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();
}
}
However, it is returning an ArrayIndexOutOfBoundsException. My desired output is supposed to be:
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
(The .. pertains to whatever is in between and must print 0 as frequency.)
Stack Trace:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at
com.mypackage.mp.AsciiCounter.displayAsciiOccurrence(AsciiCounter.java:20)
at
com.mypackage.mp.AsciiCounter.main(AsciiCounter.java:31)
The error is in your printing loop:
System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[caInputWords[i]]);
Since i hasn't changed since the first loop, it is equal to caInputWords.length at this point.
I guess you just meant:
System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);
As a side note, you might not want to print all the ASCII characters themselves. Some of them don't represent printable characters or are whitespace. One simple way around this is to check that iaCount[ctr] > 0 before printing so you only print characters that were in the String to begin with.
You have a problem in your second loop:
for(int ctr = 0; ctr < 256; ctr++) {
System.out.println(ctr +"\t" + (char) (ctr) + "\t"
+ iaCount[caInputWords[i]] // HERE
);
}
You meant iaCount[ctr]! You use i which is 256 when you enter this loop, since it has been set to this value by your previous loop. And since the iaCount array is only 256 chars long, this index is out of bounds.
Also, you fail to check what happens if you enter a non ASCII character.
To avoid this kind of error, change your first for loop to:
for(int i = 0; i < 256; i++)
Doing so in your first loop would have shown that i didn't exist in the second.
the i variable has not been reset. but you don't need to use variable i at all after the frequency calculation. You need to use ctr for frequency of all the characters.
for(int ctr = 0; ctr < 256; ctr++) {
System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);
}
That line can throw exception.
System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[caInputWords[i]]);
Change it to that
for(int ctr = 0; ctr < 256; ctr++) {
System.out.println(ctr +"\t" + (char) (ctr) + "\t" + iaCount[ctr]);
}
Related
I am trying to create a code that reads through a file and prints out the following:
number of lines of the file
the frequency of each letter
the frequency of each non-alphabetic character
I want to create a histogram for the frequency of the letters and numbers but I can't seem to find a solution around it. If anything i would want the output to look like this:
A ***** - 5
B *** - 3
C ******* - 7
My output looks like this:
*********************
*********************
*********************
A 263
B 130
C 50
etc.
This is how you do the task. It counts the number of lower case letters and prints the stars as well in addition to the frequency, just as you wanted.
Here is the general code (paragraph is the string that contains the content of your file):
int[] lettercount = new int[26];
for(int i = 0; i < 26; i++){
//Set every single number in the array to 0.
lettercount[i] = 0;
}
for(char s : paragraph.toCharArray()){
int converted = (int) s;
converted -= 97;
if(converted >=0 && converted <=25){
lettercount[converted] += 1;
}
}
//Print out the letter with the frequencies.
for(int i = 0; i < 26; i++){
char convertback = (char) (i+97);
String stars = "";
for(int j = 0; j < lettercount[i]; j++){
stars += "*";
}
System.out.println(convertback + " " + stars + " - " + lettercount[i]);
}
This should work for lowercase letters. If you want to do uppercase letters, lettercount[] should be 52 elements long. You would also have to check if converted (in the second for loop), after subtracting 97 is negative, and if it is, you would add back 58.
I hope this helps! If you have any problems, just comment below.
This is the code for a method which creates a magic square. n is the length of the square. It has to look like:
static int[][] magicSquare(int n) {
int[][] square=new int[n][n];
I don't understand this k=(k+1)%n; especially, why is it %n ?? Doesn´t that put k to 1 every loop again?
for (int i=0; i<n; i++){
in k=i;
for (int j=0; j<n; j++){
square[i][j]=k+1;
k=(k+1)%n;
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
The % in Java is used for modular division. Whenever the operator is applied the right-hand operand will be subtracted as many times as it can from the left-hand operand and what's left will be the output. You can easily check it by dividing the left-hand operand by the right-hand operand and take the leftover as an integer. In the case of a%b it will be like
a - (a/b)*b.
here are some examples:
10 % 4 = 2 // 2*4 = 8 + 2 = 10
10 % 5 = 0 // 2*5 = 10 + 0 = 10
0 % 4 = 0 // result here is 0 thus 0*4 = 0 + 0 = 0
// if you try to extract 4 from 0, you will not succeed and what's left will be returned (which was originally 0 and it's still 0)...
In your case:
k = (k + 1) % n;
is assuring that the value of k will never exceed 4, thus if it is dividable by 4 then it will be divided and the leftover will be written there. In the case when k is exactly 4 you will have the value of 0 written down into k but since you are always adding k + 1 it is writing the value of 1.
For beginners I do recommend to print the values you are interested in and observe how do the data migrate. Here I've added some printlns for you just to get the idea. Run the code and test it yourself. I do believe the things are going to be a bit cleaner.
public static void main(String[] args) {
int n = 4;
int[][] square = new int[n][n];
System.out.println("--------------");
for (int i = 0; i < n; i++) {
int k = i;
System.out.println("Filling magic cube line " + (i + 1) + ". The k variable will start from " + i + "."); // i initial value is 0 so we add 1 to it just to get the proper line number.
for (int j = 0; j < n; j++) {
System.out.println("Filling array index [" + i + "][" + j + "] = " + (k + 1)); // array indexes start from 0 aways and end at array.length - 1, so in case of n = 4, last index in array is 3.
square[i][j] = k + 1; // add 1 to k so the value will be normalized (no 0 entry and last entry should be equal to n).
k = (k + 1) % n; // reset k if it exceeds n value.
}
System.out.println("--------------");
}
Arrays.stream(square).forEach(innerArray -> {
Arrays.stream(innerArray).forEach(System.out::print);
System.out.println();
});
}
You could always play around and refactor the code as follows:
public static void main(String[] args) {
int n = 4;
int[][] square = new int[n][n];
System.out.println("--------------");
for (int i = 1; i <= n; i++) {
int k = i;
System.out.println("Filling magic cube line " + i + ". The k variable will start from " + i + ".");
for (int j = 0; j < n; j++) {
System.out.println("Filling array index [" + (i - 1) + "][" + (j - 1) + "] = " + k); // array indexes start from 0 aways and end at array.length - 1, so in case of n = 4, last index in array is 3. Subtract both i and j with 1 to get the proper array indexes.
square[i - 1][j - 1] = k;
k = (k + 1) % n; // reset k if it exceeds n value.
}
System.out.println("--------------");
}
Arrays.stream(square).forEach(innerArray -> {
Arrays.stream(innerArray).forEach(System.out::print);
System.out.println();
});
}
Remember that the array's indexing starts from 0 and ends at length - 1. In the case of 4, the first index is 0 and the last one is 3. Here is the diff of two implementations, try to see how does the indexes and values depends both on the control variables i and j.
https://www.diffchecker.com/x5lIWi4A
In the first case i and j both start from 0 and are growing till they it's values are both less than n, and in the second example they start from 1 and are growing till they are equal to n. I hope it's getting clearer now. Cheers
Can someone please explain this code for me, especially this part.
int lastpos = message.length() - 1;
Why did he add - 1 ?
==
System.out.print("What is your message? ");
String message = kb.nextLine();
System.out.println("\nYour message is " + message.length() + " characters long.");
System.out.println("The first character is at position 0 and is '" + message.charAt(0) + "'.");
int lastpos = message.length() - 1;
System.out.println("The last character is at position " + lastpos + " and is '" + message.charAt(lastpos) + "'.");
System.out.println("\nHere are all the characters, one at a time:\n");
for ( int i=0; i < message.length(); i++ )
{
System.out.println("\t" + i + " - '" + message.charAt(i) + "'");
}
int a_count = 0;
for ( int i=0; i<message.length(); i++ )
{
char letter = message.charAt(i);
if ( letter == 'a' || letter == 'A' )
{
a_count++;
}
}
System.out.println("\nYour message contains the letter 'a' " + a_count + " times. Isn't that interesting?");
}
}
Because indices start at 0 . If you have a list of {0, 1, 2}, note that it has a length of 3, but the last index is only 2. - 1 is used to correct for that.
If you iterated to the element at index 3 (the length of the list), you would go off the end of the list, causing an IndexOutOfBoundsException.
Note, I used lists as an example for ease of understanding, but it's exactly the same when it comes to Strings. All iterables start at an index of 0.
Suppose you have a String "Abdullah" and you want to print last character of that string then
int lastpos = message.length() - 1
Iine gives you last character of that String.
So in given code that line print the last character of the input String.
I'm trying to change my code so that it prints how the frequency of the letters and not how many there is e.g. "I am a man I am a man" should give the same answer as "I am a man" since the relative proportions of each letter to the whole sequence is the same.
So the desired output would be:
Letter A: Count: 0.43
Letter I: Count: 0.14
Letter M: Count: 0.29
Letter N: Count: 0.14
So the count will always add up to 1.0.
At the moment, my code just counts and displays how many times the letter appears, is this simple to change?
//
You could try something like this to get the percent of total characters:
int total = 0;
for(int i = 0; i < lettersArray.length; i ++)
{
total += letterArray[i];
}
for (char characters = 'a'; characters <= 'z'; characters++) {
int index = characters - 'a';
//print out the analysis
System.out.println("'" + characters + "' entered " + (((double)letterArray[index] / (double)total))
+ " times");
}}}
System.out.println("'" + characters + "' entered " + letterArray[index] /
(double)line.length() + " times");
I have a task to print n frequently used words based on their count values across multiple files.
Now the issue is after printing n words, I have to print all the ties at the last position
for instance if I printed 10 frequently used words based on the highest count
and the output comes like this when I use a for loop.
CODE
int listSize = newList.size() >= 10 ? 10 : newList.size();
for (int k = 0; k < listSize; k++) {
Words w = newList.get(k);
System.out.println("Word : " + ++j + " " + w.getWord() + " "
+ w.getCount());
// System.out.println(w.getWord());
}
OUTPUT :
word 1 : liked 104
word 2 : hello 98
....
....
....
word 10 : picnic 15
now If I encounter words further with the same count that is 15 I have to print them also
if I have five words with the same word count 15
I have to print all of them that is all ties for the last position must be reported like this
**OUTPUT :**
word 11 : camera 15
word 12 : monkey 15
word 13 : carrot 15
word 14 : penguin 15
word 15 : bottle 15
how to implement this case guide me thanks in advance
If newList is sorted by getCount then the simpliest way to print words with same count as last printed word is:
int k; // init k before the cycle
for (k = 0; k < listSize; k++) {
Words w = newList.get(k);
System.out.println("Word : " + ++j + " " + w.getWord() + " "
+ w.getCount());
// System.out.println(w.getWord());
}
if (k > 0) {
int lastCount = newList.get(k - 1).getCount(); // last printed count
// print words from the k-th
while (k < newList.size()
&& newList.get(k).getCount() == lastCount) {
Words w = newList.get(k);
System.out.println("Word : " + ++j + " " + w.getWord() + " "
+ w.getCount());
++k;
}
}