Change from finding max number to find words in array - java

I have a function that is searching for max number in the array. I want to make the function to search for more than one word that is entered from console.
As example I enter two words(car,ride) they're added to array and then "surasti" function is comparing them if they're in the array.
I have tried to do it on my own, but I'm a started and it seems too hard :(
Function that is searching:
public static produktas[] surasti (produktas G[], int n){
produktas A[] = new produktas[1];
produktas max = G[0];
for (int i=1; i<n; i++)
if (max.gautiSvori()<G[i].gautiSvori()) max = G[i];
A[0]=max;
return A;
}
The code that is calling that function (A is the array that you have to search in.):
case 5:
B = surasti(A, n);
System.out.println("Sunkiausias gyvunas yra:");
spausdinti_sar_ekrane(B, B.length);
break;
The produktas class:
class produktas {
private String pavadinimas;
private String salis;
private Double svoris;
private Double kaina;
produktas() {}
produktas(String pav, String salis, double svoris, double kaina){
pavadinimas = pav;
this.salis = salis;
this.svoris = svoris;
this.kaina = kaina;
}
public String gautiPav (){
return pavadinimas;
}
public String gautiSali (){
return salis;
}
public double gautiSvori (){
return svoris;
}
public double gautiKaina (){
return kaina;
}
}
When I try to change the function to this (don't know if its working fine, can't test it):
public static produktas[] surasti (produktas G[], int n){
try{
BufferedReader in = new BufferedReader (new InputStreamReader (System.in));
produktas A[] = new produktas[5];
for (int j=0; j<5; j++){
System.out.println("Kokio produkto ieskosime?");
String found = in.readLine();
for (int i=1; i<n; i++){
if (found.equals(G[i].gautiPav())){
A[j] = G[i];
}
}
}
return A;
} catch(IOException ie){
ie.printStackTrace();
}
}
When I try this code I get this error at public static produktas[] surasti (produktas G[], int n){ line:
This method must return a result of type produktas[]

For the correctly complied code update your method to have a return in catch block as well.
public static produktas[] surasti(produktas G[], int n) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
produktas A[] = new produktas[5];
for (int j = 0; j < 5; j++) {
System.out.println("Kokio produkto ieskosime?");
String found = in.readLine();
for (int i = 1; i < n; i++) {
if (found.equals(G[i].gautiPav())) {
A[j] = G[i];
}
}
}
return A;
} catch (IOException ie) {
ie.printStackTrace();
return null; // Expected return from catch block
}
}
To understand the issue properly start using IDE like eclipse rather than simply using a notepad and compiling code through java/javac
A more suitable code would be like as below. Type q in console when u want to exit from the program.
public static produktas[] surasti(produktas G[], int n) {
BufferedReader consoleReader = null;
produktas produktasFound[] = new produktas[5]; // Initalize array to store the produkt found
try {
consoleReader = new BufferedReader(new InputStreamReader(System.in));
boolean exit = false;
produktas produktasFound[] = new produktas[5];
int j = 0;//current produktFound index
while (!exit) {
System.out.println("Kokio produkto ieskosime?");
String produktPav = in.readLine();
if ("q".equals(produktPav)) {
exit = true;
} else {
for (int i=1; i<n; i++){
if (found.equals(G[i].gautiPav())){
A[j] = G[i];
j++;
}
}
}
if(j == 5)
exit = true;
}
return produktasFound; // return all the 5 produktas found
} catch (IOException e) {
e.printStackTrace();
} finally {
if (consoleReader != null) {
try {
consoleReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return produktasFound; //If no produkt is found from the array returned is blank
}

Your comparison operator is not correct. Try the following code :
public static produktas surasti(produktas G[]) {
produktas max = G[0];
for (int i = 0; i < G.length; i++) {
if (max.gautiSvori() < G[i].gautiSvori()) {
max = G[i];
}
}
return max;
}
You need to pass the array and set the first element of the array as the maximum as by default first. Next iterate through the array and check whether there is a produktas with a higher value of svoris. If so, change the max to point to this new produktas. At the end of the for loop, you will now have the max set to the produktas with the highest value of svoris.
There are few things in the code that you can fix for better quality code.
You don't need to pass the array size to the surasti method. We can just do a G.length (in the code above I have done that).
Best practice is to user Camel case for Java classes. Therefore instead of produktas, use Produktas
Use meaningful names for variables instead of A, G, etc

Related

Exception in thread "main" java.util.InputMismatchException errors

I can't exactly figure out what the issue is. I think it has to do with the array list but I'm not quite sure how to fix this. I've tried to instead of returning the array list, add to a new array list created in the main function but that didn't work. The error I keep getting is:
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at fileAnalyze.inputFileList(fileAnalyze.java:18)
at fileAnalyze.main(fileAnalyze.java:6)
import java.util.*;
import java.io.*;
public class fileAnalyze {
public static void main(String[] args){
ArrayList<Integer> inputFileInfo = inputFileList("inputFile.txt");
int count = numberAmount(inputFileInfo), small = inputFileInfo.get(argmin(inputFileInfo)),
big = inputFileInfo.get(argmax(inputFileInfo)), theAverage = average(inputFileInfo);
fileCreate(count, small, big, theAverage);
}
private static ArrayList <Integer> inputFileList(String n){
Scanner reading = new Scanner(n);
ArrayList<Integer> inputFileData = new ArrayList<Integer>();
while (reading.hasNextLine()){
int data = reading.nextInt();
inputFileData.add(data);
}
reading.close();
return inputFileData;
}
private static int numberAmount(ArrayList<Integer> n1){
return n1.size();
}
private static int argmin(ArrayList<Integer> n2){
int arg= -1, x = 0;
for (int i = 0; i < n2.size(); i++){
if (n2.get(i) < x){
arg = i;
x = n2.get(i);
}
}
return arg;
}
private static int argmax(ArrayList<Integer> n3){
int arg= -1, x = 0;
for (int i = 0; i < n3.size(); i++){
if (n3.get(i) < x){
arg = i;
x = n3.get(i);
}
}
return arg;
}
private static int average(ArrayList<Integer> n4){
int total = 0;
for (int i = 0; i < n4.size(); i++){
total = total + n4.get(i);
}
int average = total / n4.size();
return average;
}
private static void fileCreate(int numberCount, int minNum, int maxNum, int avg){
try {
File outputFile = new File("outputFile.txt");
if (outputFile.createNewFile()) {
}
else {
System.out.println("File already exists");
}
FileWriter writing = new FileWriter("outputFile.txt");
writing.write("**********");
writing.write("There are " + Integer.toString(numberCount) + " numbers in this file.");
writing.write("The minimum number is " + Integer.toString(minNum));
writing.write("The maximum number is " + Integer.toString(maxNum));
writing.write("The average is " + Integer.toString(avg));
writing.close();
} catch (IOException e){
System.out.println("An error has occured.");
e.printStackTrace();
}
}
}
I would change your code to
while (reading.hasNextLine()){
String line = reading.nextLine ();
try{
Integer data= Integer.valueOf(line);
inputFileData.add(data);
}
catch (NumberFormatException ex){
ex.printStackTrace();
}
}
This will allow you to read your file even if it has blanks lines or other non-integer junk
Refer the official docs:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
So either ensure your input is a legal int value or add the try/catch clause.
Problem:
Here : int data = reading.nextInt();
You are trying to get an Integer from the file but a file may contain characters and not just integers.
Solution:
To make sure you read only integer from the file, you need to catch an expection if the file contains a non desirable input.
Change this line :
int data = reading.nextInt();
To:
try {
int data = reading.nextInt();
catch(InputMismatchException e) {
//Your code for handing exception.
}

Merge strings of ints

I am stuck ... can anyone tell me how can i do this:
Here is the required input and output:
input: [4, 2, +, 8, +, 2, 5, multiply sign, 2]
output: [42,+,8,+,25,multiply sign,2]
This was my last try and it output nothing :
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
for (int i = 0; i < data.size(); i++) {
String num = "";
try {
num += Integer.parseInt(data.get(i));
for (int i2 = i; i < data.size(); i++) {
try {
num += Integer.parseInt(data.get(i2));
} catch (NumberFormatException e) {
e.printStackTrace();
i = i2 - 1;
temp.add(num);
num = "";
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
temp.add(data.get(i));
}
}
return temp;
}
The i2 variable doesn't iterate, which is why you are not getting any output. That loop isn't necessary anyway. Putting the test to see if a string is a number in its own function simplifies things a little.
Here is a revised solution, and a link to a place you can test it.
http://tpcg.io/l2xbRASM
public static Boolean isNumeric(String value) {
try {
Integer.parseInt(value);
return true;
} catch(NumberFormatException e) {
return false;
}
}
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
String num = "";
for (int i = 0; i < data.size(); i++) {
// HelloWorld is the name of the class I am testing this in.
if(HelloWorld.isNumeric(data.get(i))) {
num += Integer.parseInt(data.get(i));
} else {
temp.add(num);
// this line adds the arithmetic operator to the resulting output
temp.add(data.get(i));
num = "";
}
}
// add number that remains to the array
if(num != "")
temp.add(num);
return temp;
}
I hope this adds to the answers other people have given.
import java.util.*;
import java.lang.*;
import java.io.*;
class Sample
{
public static void main (String[] args) throws java.lang.Exception
{
List<String> sampleData = new ArrayList<String>();
sampleData.add("1");
sampleData.add("2");
sampleData.add("*");
sampleData.add("8");
sampleData.add("+");
sampleData.add("2");
sampleData.add("5");
List<String> resultList = unifyNumbers(sampleData);
System.out.println(resultList);
}
public static List<String> unifyNumbers(List<String> data) {
String concatedNum = "";
List<String> resultList = new ArrayList<String>();
for(String arrVal: data) {
if(isInteger(arrVal)) {
concatedNum += arrVal;
} else {
resultList.add(concatedNum);
resultList.add(arrVal);
concatedNum = "";
}
}
if(!concatedNum.isEmpty()) {
resultList.add(concatedNum);
}
return resultList;
}
public static boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
}
It seems like Gowtham Nagarajan already gave you a better way to do it. I'd advise you to use a modified version of his code, one that checks whether your String is an Integer without a try/catch block (see this question for a discussion on why your current approach isn't really good practice).
I'll still show you what I did, just to help you understand what went wrong with your first approch and how to fix something like that.
I changed your code to make it work like you want it to. All my check prints that I used to find problems are still in there, to give you an idea how to find problems in the execution. Checks like these make it easier to follow the "flow" of your program and to find out what went wrong. You can take a piece of paper and write down every step your program goes through, the checks will show you if everything works like you want it to or if there's unwanted behavior.
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
for (int i = 0; i < data.size(); i++) {
String num = "";
try {
num = "" + Integer.parseInt(data.get(i));
System.out.println("Check 1");
for (int i2 = i + 1; i2 < data.size(); i2++) {
try {
num += Integer.parseInt(data.get(i2));
System.out.println("Check 2");
} catch (NumberFormatException e) {
System.out.println("Error inside loop");
e.printStackTrace();
i = i2 - 1;
System.out.println("To add:" + num);
temp.add(num);
num = "";
break;
}
}
} catch (NumberFormatException e) {
System.out.println("Error outside loop");
e.printStackTrace();
temp.add(data.get(i));
}
if (!num.equals("")) {
System.out.println(num);
temp.add(num);
}
}
return temp;
}
When using the print statements, I found out that your original code never left the first inside loop. The print statement at the end System.out.println(num); printed something like 44444444. Hints like this one can help you make the code work.
There were a lot of small mistakes that were reasonably easy to find this way. I suggest you try that next time. Good Luck!

Rewrite recursive function to iterative one

A short flight of stairs will be called a construction of cubes in which each next level consists of a strictly larger number of cubes than the previous level, if we count the levels from top to bottom. You need to count the number of ladders that can be built exactly from n cubes.
My solution to this task doesn't pass the time test. To fix this, I decided to try to rewrite the recursive function to the usual one, but so far it has not worked out very well.
public class main {
int n;
public static int counts(int prev_level, int n) {
if (n == 0){
return 1;
}
int count = 0;
for (int level =1; level<prev_level; level++){
if((n-level)<0)
break;
count += counts(level,n-level);
}
return count;
}
public static void main(String[] args) {
int n;
int res = 0;
int count = 0;
try {
Scanner sc = new Scanner(new File("input.txt"));
while (sc.hasNext()) {
n = Integer.parseInt(sc.nextLine());
res = counts(n+1,n);
}
} catch(IOException e) { System.out.println("Input error"); }
try{
FileOutputStream writer = new FileOutputStream("output.txt");
PrintStream p = new PrintStream(writer);
p.println(res);
writer.close();
} catch(IOException e) { System.out.println("Output error"); }
}
}

Making a Program that Reads and Writes Data - Then Computes Min, Max, Average

I'm making a program that reads some data from a text file and then takes that data and finds the minimum, maximum, and average of the numbers. For some reason I'm getting a lot of ridiculous errors I've never seen before. Here is my code:
import java.io.File;
import java.util.Scanner;
import java.io.FileWriter;
public class Lab1 {
static int count = 0;
static int[] newData2 = new int[count];
// Method for reading the data and putting it into different arrays
static int[] readData() {
File f = new File("data.txt");
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt();
}
for (int i = 0; i < newData2.length; i++) {
newData[i] = newData2[i];
return newData2;
}
} catch (Exception e) {
System.out.println("Could not read the file.");
}
}
static int min(int[] newData2) {
int min = newData2[0];
for (int i = 0; i < newData2.length; i++) {
if (newData2[i] < min) {
min = newData2[i];
}
}
return min;
}
static int max(int[] newData2) {
int max = newData2[0];
for (int i = 0; i < newData2.length; i++) {
if (newData2[i] > max) {
max = newData2[i];
}
}
return max;
}
static double average(int[] newData2) {
double average = 0;
int sum = 0;
for (int i = 0; i < newData2.length; i++) {
sum = newData2[i];
}
average = sum / newData2.length;
return average;
}
/*
* static int stddev(int[] newData2) { int[] avgDif = new
* int[newData2.length]; for(int i = 0; i < newData2.length; i++) {
* avgDif[i] = (int) (average(newData2) - newData2[i]); }
*
* }
*/
void write(String newdata, int min, int max, double average, int stddev) {
try {
File file = new File("stats.txt");
file.createNewFile();
FileWriter writer = new FileWriter("stats.txt");
writer.write("Minimum: " + min + "Maximum: " + max + "Average: " + average);
writer.close();
}catch(Exception e) {
System.out.println("Unable to write to the file.");
}
public static void main(String[] args) {
}
}
}
I have an error in my readData method, and it tells me that:
This method must return a result type of int[].
I'm literally returning an int array so I don't understand what the problem here is.
Then in my main method it says void is an invalid type for the variable main.
Here are some pointers:
each exit point of a method returning something must return something, if the line new Scanner(f); throws an exception, the first return is not reached, so you need a default one, like this:
private int[] readData() {
File f = new File("data.txt");
int count = 0;
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt(); // maybe you should handle the case where your input is too large for the array "newData"
}
return Arrays.copyOf(newData, count);
} catch (Exception e) {
System.out.println("Could not read the file.");
}
return null;
}
To reduce the size of an array, you should use Arrays.copyOf (see below)
You should avoid static fields (and in your case none are required)
Your method min and max are assuming there are elements in the array (at least one), you should not do that (or test it with an if):
private int min(int[] data) {
int min = Integer.MAX_VALUE; // handy constant :)
for (int i = 0; i < data.length; i++) {
if (data[i] < min) {
min = data[i];
}
}
return min;
}
private int max(int[] data) {
int max = 0;
for (int i = 0; i < data.length; i++) {
if (data[i] > max) {
max = data[i];
}
}
return max;
}
In your average method there are a few mistakes:
private double average(int[] data) {
int sum = 0;
for (int i = 0; i < data.length; i++) {
sum += data[i]; // here if you want a sum it's += not =
}
return (1.0 * sum) / data.length; // you want a double division, local "average" was useless
}
arrays are iterables so you can use "new style" for loops:
for (int value : newData) {
// use value
}
Some reading:
Java Integer division: How do you produce a double?
“Missing return statement” within if / for / while
static int[] readData() {
File f = new File("data.txt");
int[] newData = new int[100];
try {
Scanner s = new Scanner(f);
while (s.hasNext()) {
newData[count++] = s.nextInt();
}
for (int i = 0; i < newData2.length; i++) {
newData[i] = newData2[i];
return newData2;
}
} catch (Exception e) {
System.out.println("Could not read the file.");
}
//TODO: return something here if there is some kind of error
}
Because of the try-catch block you need to account for every possibility that could occur. When you return the array when the program succeeds you are expecting a return, but when there is an exception the program still expects a return value, but you did not provide one.

Using Arrays.sort, empty array returned

I'm using the Arrays.sort method to sort an array of my own Comparable objects. Before I use sort the array is full, but after I sort the array and print it to System nothing is printing out. EDIT. the array prints nothing at all. not empty line(s), just nothing.
here is the code for my method which uses sort :
public LinkedQueue<Print> arraySort(LinkedQueue<Print> queue1)
{
Print[] thing = new Print[queue1.size()];
LinkedQueue<Print> newQueue = new LinkedQueue<Print>();
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
Arrays.sort(thing);
for(int j = 0;j<thing.length-1;j++)
{
System.out.println(thing[j]); //printing does not work here
newQueue.enqueue(thing[j]);
}
return newQueue;
}
and here is the class for the Comparable object called Print.
public class Print implements Comparable<Print>
{
private String name;
private int numPages,arrivalTime,startTime,endTime;
public Print(String n, int p, int time, int sTime, int eTime)
{
name = n;
numPages = p;
arrivalTime = time;
startTime = sTime;
endTime = eTime;
}
public int getPages()
{
return numPages;
}
public int compareTo(Print other)
{
if(this.getPages()<other.getPages())
return -1;
else if(this.getPages()>other.getPages())
return 1;
else
return 0;
}
public String toString()
{
return name+"("+numPages+" pages) - printed "+startTime+"-"+endTime+" minutes";
}
}
Your last for loop doesn't print the last element in the array. If the array has only one element, it won't print anything at all. Change to:
for (int j = 0; j < thing.length; j++) //clean code uses spaces liberally :)
{
System.out.println(thing[j]);
newQueue.enqueue(thing[j]);
}
or (if supported by the JDK/JRE version used):
for (Print p : thing)
{
System.out.println(p);
newQueue.enqueue(p);
}
I hope the problem is this part of code
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
replace the above with
for(int i = 0; !queue1.isEmpty() ; i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}

Categories