The goal of this code was to create a program using main method java to analysis a piece text which has been entered from a user.
They do this by entering the text into a scanner which is then analysed by the program. The analysis is to produce word frequency, for example " This is a test" produces this results:
This is a test
1 letter words: 1
2 letter words: 1
3 letter words: 0
4 letter words: 2
5 letter words: 0
The bit that I'm stuck on is producing a mean/average, My guts telling to divide
counts.length by str.length but I'm not the Best at java and I've tried to implement this but all I get are errors. I'm not expecting anyone to just hand me code, but if someone could give me a hint in what I should do or just point me the right direction it would be greatly appreciated.
Code:
import java.util.Scanner;
public class Text_AD {
public static void main (String[] args) {
while(true){
Scanner input = new Scanner(System.in);
System.out.println("Enter text: ");
String s;
s = input.nextLine();
System.out.println("" + s);
String[] strings = s.split(" ");
int[] counts = new int[6];
for(String str : strings)
if(str.length() < counts.length) counts[str.length()] += 1;
for(int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
}}}
By average, I am assuming that you mean the mean length. I am also assuming you want to get a floating point mean. In which case you just need to divide the total of all the lengths in strings by the length of the array itself.
You could do something like the following;
int total = 0;
for(String s : strings) total += s.length();
System.out.println((double)total/strings.length);
I hope this helps.
Without breaking up your code much, you could run a for loop through your counts[] array, adding up all the values, and then dividing by counts.length to get the average.
Be aware of type casting though. You may want to do Double division instead of integer.
It this what you are looking for?
import java.util.Scanner;
public class While_Loop {
public static void main (String[] args) {
int lengthSum, wordCount;
lengthSum = wordCount = 0;
while(true){
Scanner input = new Scanner(System.in);
System.out.println("Enter text: ");
String s;
s = input.nextLine();
System.out.println("" + s);
String[] strings = s.split(" ");
int[] counts = new int[6];
for(String str : strings)
if(str.length() < counts.length) counts[str.length()] += 1;
wordCount++;
lengthSum += str.length();
for(int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
System.out.println("Average: " + lengthSum/wordCount);
}}}
NOTE: I only added stuff to your code. The way it is written is pretty messy. I'd clean up some of the for loops and the brackets at the end for practice making the code more readable.
When I understand you correct you should have one variable int totalCount = 0; where you add
totalCount += i*counts[i]; in your last for loop.
After the loop you can simply divide through the size-1 (because 0 does not count)
double average = totalCount/(counts.length-1);
Alternative way
You take the inputstring length without the spaces and divide it by the number of spaces + 1 (which is equal to the number of words)
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
System.out.println("Enter text: ");
String s = "This is a sample text";
System.out.println("" + s);
String[] strings = s.split(" ");
for(String str : strings) {
Integer counter = map.get(str.length())==null?0:map.get(str.length());
map.put(str.length(),counter++);
}
Integer sum=0;
Integer counter=0;
for(Integer len : map.keySet()) {
sum+=len*map.get(len);
counter+=map.get(len);
}
Double average = Double.valueOf(sum/counter);
Or you can combine the loops
Few suggestions which might help you (not related to the specific question).
Choose a meaningful class name rather than While_Loop .
Do, Scanner input = new Scanner(System.in); before the start of the loop.
As soon as you read each line, do the following.
Split the line using "\\s+" .
Create a HashMap with Key as Count (Integer) and Value as a list of Words with that count. Create this outside the loop.
For each split word,,get the length . and check if the map already contains the count, get the list (value), add he current word to it. else, add a new entry with the word as the single entry in the list.
Get the keySet of the map, add values of all keys i.e, *count * number of elements in the list*. then divide by total number of elements.
And yes, I know this is a very big change (something you might as well ignore..). But this is the right way to go.
Related
I am practising with algorithms, and I have this problem where I have to state how many of each of the letters in the word appear. e.g. input = floor , output = f1l1o2r1. I have the following code:
public static void main(String[] args) {// TODO code application logic here
Scanner inword = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
System.out.println("Enter word");
String word = inword.nextLine();
int length = word.length();
char[] wordArray = word.toCharArray();
for(int i = 0; i<length; i++){
int count = StringUtils.countMatches(word, String.valueOf(wordArray[i]));
System.out.print(wordArray[i] + count);
}
}
but instead I get this as output: 103109113113115 , when I enter floor as input
Your problem is that you print out the ascii-code value of the char. Try
System.out.print(wordArray[i]+"" + count);
instead of
System.out.print(wordArray[i] + count);
First, you should use countMatches(word, wordArray[i]); But that will not solve the entire problem. For example, your approach would lead to an output of "f1l1o2o2r1", and for the word "boohoo", you would get "b1o4o4h1o4o4".
You need to rethink how to do it if you want the output to show the number of consecutive same letters ("b1o2h1o2"), or if you want the number of each letter, specified only once, in order of first appearance ("b1o4h1"), or the number of appearances of letters alphabetically ("b1h1o4").
Considering the implementation of StringUtils.countMatches() is correct, the problem lies in the line
System.out.print(wordArray[i] + count);
Here, when you do wordArray[i], it returns a char. However, doing +count, converts that char into its ASCII value, and adds up count to it.
To fix it, try doing:-
System.out.print(wordArray[i] + " " + count);
I am learning about arrays and I did quiet a few experiments, most of them went well, however now I'm stuck.
What I want to archive is, find if an specific value (String, int or whatever), exists inside an Array and if it does, use that value for something i.e the code below which I basically count how many times that value was present inside the array:
package arraysOnly;
import java.util.*;
public class ArrayContainsString
{
public static void main(String[]args)
{
Scanner sc = new Scanner(System.in);
int arraySize = 0;
int wordCount = 0;
System.out.println("How many words are you gonna type?: ");
arraySize = sc.nextInt();
String[] words = new String[arraySize]; // Simple array, the size of which will be decided from the user-input
for(int count = 0; count < arraySize; count++)
{
System.out.println("Enter your " + (count+1) + ": ");
words[count] = sc.next();
}
//Basically this is the part I'm having troubles
if(in_array("ubt", $words)
{
wordCount++;
}
}
}
I know about this,
if(Arrays.asList(words).contains("ubt"));
which basically converts the array into an List / ArrayList or whatever, however I want to treat this as an array only if possible.
An array is the wrong data structure; a Set is the weapon of choice:
Set<String> words = new HashSet<>()
for (int count = 0; count < arraySize; count++) {
System.out.println("Enter your " + (count+1) + ": ");
words.add(sc.next());
}
if (words.contains("ubt"))
wordCount++;
}
The contains() method of a HashSet completes in constant time not matter how large the set is. Although performance is irrelevant for small input sizes like this usage, it's good to get in the habit of choosing the right tools for the job. It also makes your code cleaner.
Generally speaking, don't use arrays unless you absolutely have to; they are only rarely used in commercial code.
The simple solution
public static boolean contains(String toFind, String[] strings) {
for (String str : strings) {
if (str.equals(toFind)) return true;
}
return false;
}
EDIT:
To increase it after the user inputs a word, use this in the loop:
System.out.println("Enter your " + (count+1) + ": ");
words[count] = sc.next();
if (words[count].equals("ubt")) wordCount++;
You can just iterate over array
for (String str : array){
if(str.equals("ubt")){
wordCount++;
}
}
Edit:
It's just equivalent to a normal for loop
for(int i=0; i<array.length; i++) {
if(array[i].equals("ubt")){
wordCount++;
}
}
I am attempting to calculate the average word length of user input in Java in a very simplistic way. The actual "math" of the code I've already completed, and it seems to be working quite well, but there are some odd house keeping things I need to address in order to complete the code.
So far, I have the following:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
int count = 0;
double sum = 0;
while (sc.hasNext()) {
String userInput = sc.next();
double charNum = userInput.length();
sum = charNum + sum;
count++;
double average = 0;
if (count > 0) {
average = sum / count;
}
System.out.println("Average word length = " + average);
}
}
}
The end result output should look like this:
run:
Please type some words, then press enter:
this is a test
Average word length = 2.75
BUILD SUCCESSFUL (total time: 10 seconds)
However, the output is looking like this:
run:
Please type some words, then press enter:
this is a test
Average word length = 4.0
Average word length = 3.0
Average word length = 2.3333333333333335
Average word length = 2.75
Based on the code that I've written, how can I change it so that:
The "average word length" is only printed one final time.
The program ends after the user presses enter
Thank you for any suggestions.
You're calculating the average every single time you enter a word, which is not what you want. Also, the while loop will continue even if enter is pressed. Try this:
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
int count = 0;
double sum = 0;
String input = sc.nextLine();
String[] words = input.split("\\s+"); // split by whitespace
// iterate over each word and update the stats
for (String word : words) {
double wordLength = word.length();
sum += wordLength;
count++;
}
// calculate the average at the end
double average = 0;
if (count > 0) {
average = sum / count;
}
System.out.println("Average word length = " + average);
Output:
Please type some words, then press enter:
this is a test
Average word length = 2.75
You just need to move your System.out.println after the loop and declare average out of the loop to prevent scope issues. However, it is more elegant to do it this way :
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
double average = 0;
for (String word : sc.nextLine().split("\\s+"))
average += word.length();
average /= words.length;
System.out.println("Average word length = " + average);
sc.close();
}
}
sc.nextLine() returns the entire line typed by the user (without the last "\n" character) and split("\\s+") splits this line using the regex \s+, returning an array containing the words. This regex means to split around any non-empty sequence of blank characters.
Just get System.out.println(...) out of the while loop. And declare average variable before the loop body.
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please type some words, then press enter: ");
String words = sc.nextLine();
int count = 0;
double sum = 0;
double average = 0;
sc = new Scanner(words);
while (sc.hasNext()) {
String userInput = sc.next();
double charNum = userInput.length();
sum = charNum + sum;
count++;
if (count > 0) {
average = sum / count;
}
}
System.out.println("Average word length = " + average);
}
A) Print your output outside of the loop when all of the averaging has already been done
B) Use Date.getTime() to get the time at the start of the program after the user has inputted their sentence, and store it in a variable, then at the end of the program, get the time again, subtract it from the old time, and divide by 1000 to convert it from milliseconds to seconds. After that you can just print it out however you want it formatted
C) call sc.readLine() after you have outputted everything so that when they press enter that line will stop blocking and let the program end.
I'm trying to implement a infinite while loop into my word frequency java code. The goal of this code was to create a program using main method java to analysis a piece text which has been entered from a user.
They do this by entering the text into a scanner which is then analysed by the program.
import java.util.Scanner;
public class WordFreq {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter text: ");
String s;
s = input.nextLine();
System.out.println("" + s);
String[] strings = s.split(" ");
int[] counts = new int[6];
for(String str : strings)
if(str.length() < counts.length) counts[str.length()] += 1;
for(int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
input.close();}
}
The user then can re enter a piece of text to be analysed over and over again.
I have this piece of code, which has a infinite while already in, but when I try to merge the two I keep getting errors.
import java.util.Scanner;
public class WhileLoop {
public static void main(String args[])
{
Scanner scan = new Scanner(System.in);
String line="";
while((line=scan.nextLine())!=null)
{
String tokens [] = line.split(" ");
for(int i=0;i<tokens.length;i++)
{
System.out.println(tokens[i]);
}
}
}
I'm not the Best at java and I'm not expecting anyone to just hand me code, but if someone could give me a hint in what I should do or just point me the right direction it would be greatly appreciated.
You have not clarified how do you actually merged your code and what kinds of errors ar eyou getting but your while loop is not good. You need to wait for user input INSIDE an "infinite" loop.
while(true){ //Infinite loop
Scanner in = new Scanner(System.in);
while(in.hasNextLine())//Check for input
System.out.println(in.nextLine()); //Process input
}
This way every time the user pressed 'Enter' you process his input.Of course you can do anything you like with in.nextLine()' orin.next()` and your while loop could have an ending condition cause i doubt you want an 100% infinite loop, but the structure should be the same. Hope this helps.
EDIT: Try the following code:
while(true){
Scanner input = new Scanner(System.in);
System.out.println("Enter text: ");
String s;
s = input.nextLine();
System.out.println("" + s);
String[] strings = s.split(" ");
int[] counts = new int[6];
for(String str : strings)
if(str.length() < counts.length) counts[str.length()] += 1;
for(int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
}
Although its quite unlikely you need a true infinite loop, so consider putting some stopping condition in your while loop.
This is a bit confusing, but let me try anyway.
If you merge the two blocks of code then you should try printing count[i] instead of token[i] in the while loop. And the limit of the loop should be count.Length not token.Length.
Now, if I am not wrong, this would print the frequency of 1 to 5 lettered words infinitely taking in your inputs from the first block of the code.
Ok so I wrote a program which asks user to input a number and then reverse it. I was successful in it however the program does not reverses numbers that end with a 0. for example if i enter 1234 it will print out 4321 however if i input 1200 it will only output 21. I tried converting the number that is to become output into string. Please help me understand where I am doing it wrong. Just remember I am a beginner at this :). Below is my code.
import java.util.*;
public class ReverseNumber
{
public static void main (String [] args)
{
Scanner n = new Scanner(System.in);
int num;
System.out.println("Please enter the number");
num = n.nextInt();
int temp = 0;
int reverse = 0;
String str = "";
System.out.println("The number before getting reversed " + num);
while (num != 0)
{
temp = num % 10;
reverse = reverse*10 + temp;
num = num/10;
str = Integer.toString(reverse);
}
//String str = Integer.toString(reverse);
System.out.println("The reversed number is " + str);
}
}
You're storing your reversed number as an int. The reverse of 1200 is 0021, but that's just 21 as an int. You can fix it by converting each digit to a string separately.
The problem is that you're calculating the reversed value as a number and, when it comes to numbers, there is no difference between 0021 and 21. What you want is to either print out the reversed value directly as you're reversing it or build it as a string and then print it out.
The former approach would go like this:
System.out.print("The reversed number is ");
while (num != 0)
{
System.out.print(num % 10);
num = num / 10;
}
System.out.println();
The latter approach would go like this:
String reverse = "";
while (num != 0)
{
reverse = reverse + Integer.toString(reverse);
num = num / 10;
}
System.out.println("The reversed number is " + reverse);
The latter approach is useful if you need to do further work with the reversed value. However, it's suboptimal for reasons that go beyond the scope of this question. You can get more information if you do research about when it's better to use StringBuilder instead of string concatenation.
I actually found this way really interesting, as this is not how I usually would reverse it. Just thought to contribute another way you could reverse it, or in this case, reverse any String.
public static void main()
{
Scanner n = new Scanner(System.in);
System.out.print("Please enter the number:");
int num = n.nextInt();
System.out.println("The number before getting reversed is " + num);
String sNum = Integer.toString(num);
String sNumFinal = "";
for(int i = sNum.length()-1; i >= 0; i--)
{
sNumFinal += sNum.charAt(i);
}
System.out.print("The reversed number is " + sNumFinal);
}
If you wanted to take this further, so that you can enter "00234" and have it output "43200" (because otherwise it would take off the leading zeros), you could do:
public static void main()
{
Scanner n = new Scanner(System.in);
System.out.print("Please enter the number:");
String num = n.next(); // Make it recieve a String instead of int--the only problem being that the user can enter characters and it will accept them.
System.out.println("The number before getting reversed is " + num);
//String sNum = Integer.toString(num);
String sNumFinal = "";
for(int i = num.length()-1; i >= 0; i--)
{
sNumFinal += num.charAt(i);
}
System.out.print("The reversed number is " + sNumFinal);
}
And of course if you want it as an int, just do Integer.parseInt(sNumFinal);
The reason the two zero is being stripped out is because of the declaration of temp and reverse variable as integer.
If you assigned a value to an integer with zero at left side, example, 000001 or 002, it will be stripped out and will became as in my example as 1 or 2.
So, in your example 1200 becomes something like this 0021 but because of your declaration of variable which is integer, it only becomes 21.
import java.util.Scanner;
public class Reverse {
public static void main(String args[]){
int input,output=0;
Scanner in=new Scanner(System.in);
System.out.println("Enter a number for check.");
input=in.nextInt();
while (input!=0)
{
output=output*10;
output=output+input%10;
input=input/10;
}
System.out.println(output);
in.close();
}
}