Java storing the inputs from scanner - java

When I can't use the 'list', but need to store the inputs from the scanner, how can I deal with it?
I want to make the program counting the frequencies of the inputs appearing in the inputs from scanner.
For example, if the input is
"I like apple but I like banana too"
The result is
I: 2
like: 2
apple: 1
banana: 1
but: 1
too: 1
At first I thought of making the arrays of string, and every time input comes, I put them in the array. After then, although it would require n^2 time complexity, run the for loop for each element and then check if it has the same word.
for (String str in arr){
for(String str_2 in arr){
if(strr.equals(str_2)){
count[i]++;
} // count is the array storing the frequencies.
But problem here is... when declaring the arr, I should know the input size. Other people told me to use "list" , but the usage of the "list" is restricted.
In this situation, what would be the way?

Can you use Java streams?
String[] array = {"i", "like", "apple", "but", "i", "like", "banana", "too"};
Or to get the input from the user, something like:
Scanner sc = new Scanner(System.in);
int numberOfEntries = sc.nextInt(); // defines how big the array should be
String[] array = new String[numberOfEntries];
for (int i = 0; i < numberOfEntries; i++) {
System.out.println("Enter value " + (i+1));
String word = sc.next();
array[i] = word;
}
Arrays.stream(array).collect(Collectors.groupingBy(p -> p, Collectors.counting()))
.entrySet().stream().forEach(key -> System.out.println(key.getKey() + ": " + key.getValue()));
Output:
banana: 1
but: 1
apple: 1
too: 1
like: 2
i: 2

You can do something like this by using a HashMap and iterating over the input array in a for loop and checking if the map already contains the key or not. If it contains then just increase the count in the value. If the key is not already in the map, just add it alongwith value 1.
for (String str : inputArray) {
if (map.containsKey(str)) {
map.put(str, map.get(str) + 1);
} else {
map.put(str, 1);
}
}
Finally, just iterate over the map and print with key and value pairs.

String input = "I like apple but I like banana too";
String[] words = input.split(" ");
int countfre=0;
HashMap<String,Integer> map = new HashMap<String, Integer>();
for(int i=0;i<words.length;i++){
if(!map.containsKey(words[i])){
for (int j=0;j<words.length;j++){
if(words[i].equalsIgnoreCase(words[j])){
countfre++;
}
map.put(words[i],countfre);
}
countfre=0;
System.out.println(words[i] + " = " +map.get(words[i]));
}
}
//Without java stream api.
//Stored output in Map.
Output:
banana = 1
but = 1
apple = 1
too = 1
like = 2
i = 2

Try something like,
public static void main(String[] args) {
//input
String s = "I like apple but I like banana too";
//desired output
//I: 2 like: 2 apple: 1 banana: 1 but: 1 too: 1
String[] str = s.split(" ");
String[] result = new String[str.length];
int temp = 0;
test:
for (String str1 : str) {
for (String str2 : result) {
if(str1.equals(str2)){
continue test;
}
}
result[temp++] = str1;
int count = 0;
for (String str2 : str) {
if(str1.equals(str2)){
count++;
}
}
System.out.print(str1 + ": " + count + " ");
}

Related

How to make for loop stop when scanner is at the very end of the input

I'm currently trying to make a program that will allow the user to enter any amount of integers (I'm only asking them to enter 9 for now as a test) and have the rotateArray function rotate the array of integers. For example:
input: 1 2 3 4 5
output: 5 4 3 2 1
The reason as to why I included the arraylist is because I want to make the program dynamically allocate memory so that the user can enter as many single digit inputs as well. My problem is with a for loop I'm currently using. I"m looking for a way to properly make it so that the for loop stops when it hits the very end of the user's input. I tried using scan.nextInt().isEmpty() but that did not work as intended.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("This program takes two arrays, compares them, and "
+ "determines whether the original array has been rotated and put "
+ "into another array. \nWatch what happens when the original "
+ "array = [0,1,2,3,4,5,6,7,8,9] is compared to an array with contents: \n"
+ "[9,7,5,3,1,8,6,4,2,0]");
int[] original = {0,1,2,3,4,5,6,7,8,9};
int[] notRotated = {9,7,5,3,1,8,6,4,2,0};
int[] rotatedArray = {9,8,7,6,5,4,3,2,1,0};
boolean rotation;
rotation = isRotated(original, rotatedArray);
if(rotation == true)
{
System.out.println("The original array has been rotated!");
}else{
System.out.println("The original array has not been rotated");
}
System.out.println("\n Watch what happens when the original array is compared to an array"
+ " with contents \n [9,8,7,6,5,4,3,2,1,0]");
rotation = isRotated(original, rotatedArray);
if(rotation == true)
{
System.out.println("The original array has been rotated!");
}else{
System.out.println("The original array has not been rotated");
}
ArrayList<Integer> userArray = new ArrayList<Integer>(9);
System.out.println("This program can also rotate arrays that contain "
+ "single digit integers.\n Enter 9 single digit "
+ "integers separated by spaces");
//*****************************************************
userArray.add(scan.nextInt());
for(int i = 0; i<userArray.size(); i++)
{
//*****problem
if(???????? )
break;
else
userArray.add(scan.nextInt());
}
System.out.println("The array you entered is: " + userArray.toString() +"\n");
rotateArray(userArray);
System.out.println("When your array is rotated, it looks like this: \n" +
userArray.toString());
}
public static ArrayList<Integer> rotateArray(ArrayList<Integer> userArray)
{
int replace = 0;
int inc = 1;
int indexVariable = 0;
//if number of elements equals an even number
if(userArray.size() % 2 == 0)
{
for(int i = 0; i < (userArray.size()/2);i++)
{
replace = userArray.get(i);
userArray.set(userArray.get(i),userArray.size() - inc );
userArray.set(userArray.size() - inc, replace);
inc++;
}
}
//if number of elements equals an odd number
else
{
for (int i = 0; i <(userArray.size()/2) ; i++)
{
replace = userArray.get(i);
userArray.set(userArray.get(i),userArray.size() - inc );
userArray.set(userArray.size() - inc, replace);
inc++;
}
}
return userArray;
}
The thing about the scanner is that when its reading from the console, #hasNext will only ever return false if the scanner is closed, such as when you close it or the console is no longer usable for input. Otherwise, calling it will tell the scanner to wait for input and will let you know if it is valid input (e.g if you call #hasNextInt).
So the best way IMO to solve your issue is to read the scanner as a string, then split it and process it yourself as follows.
String input=scan.nextLine();
String[] numbers=input.split(" ");
for(String number:numbers)
{
if(number.isEmpty())
continue;//check for trailing so input like 3 4 5 is read
userArray.add(Integer.parseInt(number));//You would want to add a catch here for invalid input.
}
If input: 1 2 3 4 5 and userArray.size should match original.length then you can do like this:
int size = original.length;
for (int i = 0; i < size; i++) {
int num = scan.nextInt();
userArray.add(num);
Or you can hardcode variable size:
int size = 9;
or input it from console:
int size = scan.nextInt();

This is only returning the largest letter word, when I want it to return the count for every letter word

I need to get this code to take the user input and tell me how many one-letter words, two-letter words, three-letter words, etc. there are. This code compiles, but it only gives me the number of times the word with the most letters is used. For example, if the user input were "I want to know why this is not working" The output would be one seven-letter word. It doesn't tell me how many times all the other number of letter words are used.
import java.util.*;
import java.io.*;
public class Analysis B { //open class
public static String input;
public static String stringB;
public static void main (String args []) { //open main
System.out.println("Please enter a line of text for analysis:");
Scanner sc = new Scanner(System.in);
input = sc.nextLine();
input = input.toLowerCase();
System.out.println("Analysis B:");//Analysis B
System.out.println("Word length: " + " Frequency: ");
System.out.println(AnalysisB(stringB));
} // close main
public static String AnalysisB (String stringB) { // open analysis B
String [] words = input.split(" ");
int largest = 0;
for (int i = 0; i < words.length; i++) { //open for
largest = Math.max( words[i].length(), largest); // get the largest value
} //close for
int [] frequencies = new int[ largest + 1 ];
for (int i = 0; i < words.length; i++) { //open for
frequencies[words[i].length()]++;
} //close for
for (int i = 0; i < frequencies.length; i++) { //open for
if (frequencies[i] > 0 ) { //open if
stringB =(i + "-letter words" + " " + frequencies[i]);
} //close if
} //close for
return stringB;
} // close analysis B
} //close class
Here's your problem:
stringB =(i + "-letter words" + " " + frequencies[i]);
Each time this line of code is run, it assigns a new value to stringB, over-writing the previous value. Instead, you want it to look like this:
stringB += (i + "-letter words" + " " + frequencies[i] + "\n");
The += operator will add to stringB instead of replacing it (and the "\n" will ensure it adds to a new line each time).
By the way, there's no need to import java.io.*, since it isn't used in your program. java.io deals with file operations.
Here's a way to do this with a sorted HashMap (TreeMap):
public static void AnalysisB (String input)
{
String [] words = input.split(" ");
Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
for (String w : words)
{
int len = w.length();
Integer freq = map.get(len);
if (freq == null)
{
map.put(len, 1);
}
else
{
map.put(len, freq + 1);
}
}
for (Iterator<Integer> iter = map.keySet().iterator(); iter.hasNext(); )
{
int len = iter.next();
System.out.println(len + "-letter words" + " " + map.get(len));
}
}
Note: I made the method void since you are just printing out the frequencies in the method.
Try this.
public static String AnalysisB (String stringB) {
return Stream.of(stringB.split(" "))
.map(s -> s.length())
.collect(Collectors.groupingBy(n -> n, Collectors.counting()))
.entrySet().stream()
.sorted(Comparator.comparing(e -> e.getKey()))
.map(e -> e.getKey() + "-letter words " + e.getValue())
.collect(Collectors.joining("\n"));
}
and
System.out.println(AnalysisB("I want to know why this is not working"));
result:
1-letter words 1
2-letter words 2
3-letter words 2
4-letter words 3
7-letter words 1

Accept 5 names and print the longest name?

I want to the longest name for 5 given names. I think I should use compareTo() method or length()?
Output must be like this :
enter 5 names :
Joey
Mark
Catherine
Zachery
Foster
Longest name is Catherine.
What method should I use and how? This is my code so far:
Scanner x = new Scanner(System.in);
String name = ""
System.out.print("Enter 5 names");
name = x.nextLine();
name2 = x.nextLine();
name3 = x.nextLine();
name4 = x.nextLine();
name5 = x.nextLine();
if(name.compareTo(name2)>0) //is this method right?
.compareTo tells you which string comes first in lexicographic order (<0 if s1 < s2, 0 if s1==s2, >0 if s1>s2)
String s1 = "abc";
String s2 = "def";
s1.compareTo(s2) < 0;
.length() returns the length of a string
s1.length()==3;
In your case, you need to compare based on length, so you need the latter. If it's only 5 names, you can take the first and assume it's the longest, and then read the others one by one by keeping the "longest so far" saved and comparing them as they come. After all, you only care about the longest.
If you wanted them to be sorted by length, while still keeping them all, you'd need to store them in some sort of collection (list, array), then sort it based on length.
The problem is easy enough, so I won't provide directly the code, try to grok it yourself, you can do it :)
import java.util.Scanner;
public class LenghtyName {
public static void main(String[] args) {
Scanner x = new Scanner(System.in);
/*
Instead of declaring 5 different String variable
just use String array with size = 5
*/
String[] names = new String[5];
System.out.print("Enter 5 names :");
names[0] = x.nextLine();
names[1] = x.nextLine();
names[2] = x.nextLine();
names[4] = x.nextLine();
names[5] = x.nextLine();
//Assume lenthyName as empty String
String lengthyName = "";
/*
Iterate over String array using for-each loop
*/
for (String name : names) {
/*
-Check null to avoid NullPointerException
-Trim the left and right blank space in name by #trim()
-Compare current name length with lengthyName if greater
replace the lengthyName by current name.
*/
if (name != null && name.trim().length() > lengthyName.length()) {
lengthyName = name;
}
}
/*
Print length name
*/
System.out.println("Longest name is " + lengthyName);
}
}
What about this?
Scanner in = new Scanner(System.in);
// no need to have 5 all over the code.
// Define it once to avoid "magic nubmers"
int namesCount = 5;
// fun fact: shortest name is always "". We don't have to use null
String longestName = "";
System.out.print("Enter " + nameCount + " names:");
for (int i=0; i< nameCount; i++){
// store new name from user
String candidate = in.readLine();
// is this one longer than the current longest?
if (longestName.length() < candidate.length()){
// found a longer name
longestName = candidate;
}
}
System.out.println("Longest name is " + longestName);
This gives up storing the names, as it seems you only use the longest one anyway. It also generalizes the number of names to iterate, and most importantly the variable names are meaningful names.
Here's a solution that should work:
public class LongestWord {
public static String getLongestString(String[] array) {
int maxLength = 0;
String longestString = null;
for (String s : array) {
if (s.length() > maxLength) {
maxLength = s.length();
longestString = s;
}
}
return longestString;
}
public static void main(String[] args) {
String[] toppings = {"Cheeddddddddddse", "Pepperoni", "Black Olivesddd"};
String longestString = getLongestString(toppings);
System.out.format("longest string: '%s'\n", longestString);
}
}
An easy way would be a for loop to read 5 names and find the length for largest name. Using the for loop avoids the creation of 5 deterrent string variables.
If you want to use those names later you can go for String array.
public static void main(String[] args) throws IOException {
Scanner x = new Scanner(System.in);
String name = "";
String maxName = "";
int maxLength = 0;
System.out.println("enter 5 name :");
for (int i = 0; i < 5; i++) { // read 5 names
name = x.nextLine();
if (maxLength < name.length()) { // check longest name
maxLength = name.length();
maxName = name; // store in temp variable to show
}
}
System.out.println("Longest name is " + maxName); // print largest name
}
Output:
enter 5 name :
raj
sita
gita
mukherjee
rita
Longest name is mukherjee
Here's a solution that should work with any number of entries:
Scanner x = new Scanner(System.in);
String name = "", temp="";
while (x.hasNextLine()){
temp = x.nextLine();
if (temp.length() > name.length()) name = temp;
}
System.out.println("Longest is " + name);
You'll need to Ctrl + Z to end the inputStream on Windows
this is my code for comparing 3 input strings by their length:
public static void main(String[] args) {
String string1 , string2 , string3;
Scanner input = new Scanner(System.in);
System.out.println("Enter three string names to compare");
string1 = input.nextLine();
string2 = input.nextLine();
string3 = input.nextLine();
if (string1.length()>string2.length()) {
if (string1.length() > string3.length())
System.out.println("String 1 has the longest length , length = "+string1.length());
}
if (string2.length()>string1.length()){
if(string2.length()>string3.length())
System.out.println("String 2 has the longest length , length = "+string2.length());
}
if (string3.length()>string1.length()) {
if (string3.length() > string2.length())
System.out.println("String 3 has the longest length , length = " + string3.length());
}
}
//SIMPLE JAVA SOLUTION
class GFG
{
String longest(String names[], int n)
{
String res="";
for(int i=0;i<n;i++)
{
if(res.length()<names[i].length())
{
res=names[i];
}
}
return res;
}
}

Adding contents of a String,where string s="12 computer 5 7"

In an interview they asked me this question.There is a string like "12 computer 5 7". You need to add integers within that string and answer should be 24.How can i solve this can anyone help me please.
string s="12 computer 5 7"
output should be:24
Can i use sub-string or some other process to solve it
Try this,
String input = "12 computer 5 7";
String[] splittedValue = input.split(" "); // splitted the values by space
int result = 0;
for (String s : splittedValue)
{
if (s.matches("\\d+")) // check while the input is number or not
{
result = result + Integer.parseInt(s); // parse it and add it to the count
}
}
System.out.println("Result : "+result);
Use split("[ ]") to convert the string into an array of strings separated by space and then add the integers present in each position of the array. Add it to sum if it is an integer like :-
String ar[] = s.split("[ ]");
int sum = 0;
for(int i=0;i<ar.length;i++){
try{
sum += Integer.parseInt(ar[i]);
}catch(NumberFormatException){
//not an integer.
}
}
System.out.println("Sum of integers : "+sum);
public class Main{
public static void main(String []args){
String s="12 computer 5 7";
String [] candidateNumbers = s.split(" ");
int sum = 0;
for (String num:candidateNumbers) {
try {
sum+=Integer.parseInt(num);
} catch (Exception e) {
//
}
}
System.out.println(sum);
}
}
Using Java 8 you could also write:
int sum = Arrays.stream(s.split("\\D+"))
.mapToInt(Integer::parseInt)
.sum();
Splitting on non digit characters returns an array containing the 3 numbers as strings. Note that this assumes that the input string is well formed.

How to parse a text file into two parts using Scanner

Input (white space delimited):
1 1 2 3
2 1 7
3 3 7
4 1 5
5 3 6
I would like to process these input as like:
For each line in the text file :: (first_element, e.g. 1) into an int variable (say, m) and the following (next_elements, e.g. 1 2 3) into an ArrayList (say, N)
I tried the below:
Scanner file_scanner = new Scanner(filename);
while (file_scanner.hasNextLine()) {
String[] line = file_scanner.nextLine().split("\\s+");
String str1 = line[0];
String str2 = line[1];
m = Integer.parseInt(str1);
Scanner line_scanner = new Scanner(str2);
while(line_scanner.hasNext()) {
int n = line_scanner.nextInt();
N.add(n);
}
}
But I am not able to parse the inputs as I intended to. Any kind suggestions on how to handle two parts of an input line using Scanner? or, even how to check the end of the current line (EOL) as well as how to parse the first element more easily?
try this String[] line = file_scanner.nextLine().split("\\s+",2); in your code. It will split each line into 2 tokens only.
EDIT: line[1] will contain the rest of the numbers, you do not need to parse it again.
Sorry it might not be the most efficient since it's 4:39 am:
Scanner s = new Scanner(file);
int m = 0;
List<Integer> list = null;
while(s.hasNextLine())
{
Scanner s2 = new Scanner(s.nextLine());
int count = 0;
list = new ArrayList<Integer>();
while (s2.hasNextInt())
{
if(count == 0)
{
m = s2.nextInt();
}
else
{
list.add(s2.nextInt());
}
count++;
}
System.out.println(m + " " + list);
}

Categories

Resources