How to search an element in my array after displaying the output? - java

I'm supposed to display the rainfall value for the STATE that I want to search. How do I go about doing this?
rainfall class:
package rainfallassignment;
public class StateRainfall {
double rainAmt[]; //declare array value entered by user
int num_state = 11; //number of states in west malaysia
public StateRainfall(double rain[]) {
rainAmt = rain;
}
}
Test program:
package rainfallassignment;
import java.util.Scanner;
public class TestRainfall {
public static void main(String[] arg) {
Scanner reader = new Scanner(System.in);
//declare constant to store size of array
int num_state = 11;
//declare array to store rainfall data
double rain[] = new double[num_state];
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for (int i = 0; i < num_state; i++) {
System.out.println("Enter Rain value for each state: "
+ state[i] + ": ");
rain[i] = reader.nextDouble();
}
//create rainfall object
StateRainfall rain1 = new StateRainfall(rain);
for (int i = 0; i < num_state; i++) {
System.out.println("Rainfall for " + state[i] + " is: " + rain[i]);
}
}
}
Is there a special command I should use to search and display the rainfall for a particular state?

Several remarks to your code:
Instead of having two (synchronised) arrays better use a Map. The main purpose of a Map is to associate a value to a key:
Iterating is better done with forEach, or - since java8 - with streams.
Always be careful with naming your variables. A variable name should clearly show its intention. An array called "state" is misleading when reading the code. Since it is a collection, better use the plural "states".
Constants: Your comment "declare constant to store size of array" is wrong, since you define a local variable. Constants are better defined outside methods within the class body as
private static int NUM_STATE= 11;
It is also good practice to choose another naming style for constants (here: capital letters), which helps you later reading your own code.
A resource (like Scanner) should always be closed in order to release used memory. In my example done by a try-with-resource construct. You can also use try..finally blocks.
Following these tips, your code would boil down to this:
public static void main( String[] args)
{
Scanner reader = new Scanner(System.in);
Map<String, Double> rainMap = new HashMap<>();
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for ( String s : state )
{
System.out.println("Enter Rain value for each state: "
+ s + ": ");
rainMap.put( s, reader.nextDouble());
}
rainMap.keySet().forEach(k -> System.out.println("Rainfall for " + k + " is: " + rainMap.get(k)));
}
I think, the question for "search and display" is implicitely also answered.

I suggest that your StateRainfall keep tracks of both states and rain values, like this
// class
class StateRainfall {
String[] states;
double rainAmt[]; //declare array value entered by user
int num_state; //number of states in west malaysia
public StateRainfall(String[] states, double rain[]) {
this.states = states;
rainAmt = rain;
num_state = states.length;
}
}
This will allow you to look into states array and return the corresponding rain value from the index
double getRain(String state) {
for (int i = 0; i < num_state; i++) {
if (states[i].equals(state)) {
return rainAmt[i];
}
}
return -1;
}
// Just a toString() method for convenience
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < num_state; i++) {
sb.append("Rainfall for ").append(states[i]).append(" is: ").append(rainAmt[i]);
}
return sb.toString();
}
And use all of this like
StateRainfall rain1 = new StateRainfall(state, rain);
System.out.println(rain1);
System.out.println(rain1.getRain("Kelantan"));

You can implement such thing using Map like this :
public class StateRainfall {
Map<String, Double> rainfall;
public StateRainfall(String[] states, double[] rainFall) {
this.rainfall = new HashMap<>();
for (int i = 0; i < states.length; i++)
this.rainfall.put(states[i], rainFall[i]);
}
public static void main(String[] arg) {
Scanner reader = new Scanner(System.in);
//declare constant to store size of array
int num_state = 11;
//declare array to store rainfall data
double[] rain = new double[num_state];
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for (int i = 0; i < num_state; i++) {
System.out.println("Enter Rain value for each state: "
+ state[i] + ": ");
rain[i] = reader.nextDouble();
}
//create rainfall object
StateRainfall rain1 = new StateRainfall(state, rain);
System.out.println("Enter state for rainfall report:");
String stateName = reader.next();
System.out.println("Rainfall for " + stateName + " is: " + rain1.getRainFall(stateName));
}
public double getRainFall(String state) {
return this.rainfall.get(state);
}
}

Related

How to make a Linear Search OOP approach that uses Input Scanner

So I refactored a Linear Search code that only uses the main method. My goal is to convert it into an OOP approach. But I have trouble saving the input set of integers.
// LinearSearchDriver.java
import java.util.Scanner;
public class LinearSearchDriver {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
LinearSearch linearSearch = new LinearSearch();
System.out.println("Enter number of elements");
int numElements = in.nextInt();
linearSearch.setNumberOfElements(numElements);
System.out.println("Enter " + numElements + " integers");
for (int count = 0; count < numElements; count++){
int setIntegers = in.nextInt();
linearSearch.setNumberOfIntegers(setIntegers);
}
System.out.println("Enter value to find");
int search = in.nextInt();
linearSearch.findValue(search);
}
}
//LinearSearch.java
public class LinearSearch {
private int c;
private int n;
private int array[];
public void setNumberOfElements(int n) {
this.n = n;
this.array = new int[n];
}
public void setNumberOfIntegers(int y) {
for (c=0; c < n; c++)
array[c] = y;
}
public void findValue(int search) {
for (c = 0; c < n; c++) {
if (array[c] == search) { /* Searching element is present */
System.out.println(search + " is present at location " + (c + 1) + ".");
break;
}
}
if (c == n) { /* Searching element is absent */
System.out.println(search + " is not present in array.");
}
}
}
Example output:
But when I input number 1, this is the output:
The program only reads number 2 output which I think, the last number is only the one that is saving to an array.
for (c = 0; c < n; c++) {
array[c] = y;
}
is where things go wrong. You're setting the last value passed to that function for every index in the Array.
You can adress this in several ways:
Pass an Array to the function instead of a single argument.
You can determine the current number of elements in your Array and then append the newest value "manually". See this post.
Or you could simply use a dynamic structure, such as a List and append the element to that.
Here is a rough outline for the 3rd Option:
public class LinearSearch {
private List<Integer> intList;
public LinearSearch() {
}
public void setNumberOfElements(int n) {
intList = new ArrayList<>(n); //Set the capacity here like before.
}
public void setNumberOfIntegers(int y) {
//If you want your List to always only contain the initially allowed number of elements, you could implement
// this logic here, by adding the new value and removing the "oldest" one.
intList.add(y);
}
public void findValue(int search) {
if (!intList.contains(search)) { //You can put this up here and potentially skip the looping.
System.out.println(search + " is not present in array.");
return;
}
for (int n : intList) {
if (n == search) {
System.out.println(search + " is present at location " + intList.indexOf(search) + ".");
return; //Use return to exit the method, break only exits the loop in your example, and you could print both lines.
}
}
}
}

The array from another class doesn't update when scanner is used

When I try to use scanner on another class I can't update the array.
private int numClients;
private int[] clients;
These are variables from my class Rooms.
public Hotel(String name, int numRooms, int numClients){
this.name = name;
this.numRooms = numRooms;
this.numClients= numClients;
this.clients = new int[numClients];
}
Of course I added setters and getters:
public String getName() {
return name;
}
public void setNaziv(String name) {
this.name = name;
}
public int getNumRooms() {
return numRooms;
}
public void setNumRooms(int numRooms) {
this.numRooms = numRooms;
}
public int getNumClients() {
return numClients;
}
public void setNumClients(int numClients) {
this.numClients = numClients;
}
When I tried to add it to test it in another class, name and numRooms change. numClients change too but array doesn't update.
Hotel h1 = new Hotel(" ", 0, 0);
String name= sc.nextLine();
h1.setName(name);
int numRooms= sc.nextInt();
h1.setNumRooms(numRooms);
int numClients= sc.nextInt();
h1.numClients(numClients);
h1.show();
This is the show method:
public void show(){
System.out.println("Name: " + this.name);
System.out.println("Rooms: " + this.numRooms);
System.out.println("Number of clients: " + this.numClients);
for(int i = 0; i < clients.length; i++) {
System.out.println(clients[i]);
}
}
Maybe there will be some typing errors I translated the var names to English for question purposes.
Once you have created the array, it's size is fixed. You can test this with a few rows:
int size = 10; // Start with size 10
int[] array = new int[size]; // Array is 10 elements long
System.out.println(size); // Prints 10
System.out.println(array.length); // Also prints 10
size = 1000; // Change size ??
System.out.println(size); // Prints 1000
System.out.println(array.length); // Still prints 10
Output:
10
10
1000
10
You also don't appear to actually set any elements in the array in your code. That would be something like
h1.getClients()[0] = 3;
Edit
When this line in your constructor is exectuted:
this.clients = new int[numClients];
The array is created with the size that numClients has right at that moment. After that, there is no relation between numClients and clients anymore.
You would need to create a new array, copy contents (if you want to preserve it) and reassign clients with the new array in order to change the size.
You can do this with Arrays.copyOf() :
int newLength = 20;
array = Arrays.copyOf(array, newLength);
System.out.println(array.length); // Prints 20!!
The constructor will run once for a single object. So, if you want to add more values in the clients array then a method is a must.
The main Class:
class Main {
public static void main(String[] args) {
Hotel hotel = new Hotel("romeo",5,10);
hotel.addClients(6);
hotel.addClients(10);
hotel.addClients(5);
hotel.show();
}
}
The Hotel Class:
class Hotel{
private int numRooms,numClients;
private String name;
private int clients[] = new int[10];
public Hotel(String name, int numRooms, int numClients){
this.name = name;
this.numRooms = numRooms;
this.numClients= numClients;
this.clients[0] = numClients;
}
The method to add Clients in the clients array:
public void addClients(int numClients){
for(int i = 0; i < clients.length; i++){
if(clients[i] == 0){
clients[i] = numClients;
break;
}
}
}
Show method output:
Name: romeo
Rooms: 5
Number of clients: 10
10
6
10
5
The Total number of clients can be found by summation of the clients array.
To make the array dynamic, the linked list data structure can be applied.
What I did to fix this without updating and making new methods is defining values with scanner and putting it into constructor.
public void test(){
Scanner sc = new Scanner(System.in);
System.out.print("Type in the name of Hotel: ");
String name= sc.nextLine();
System.out.print("Type in number of rooms: ");
int numRooms = sc.nextInt();
System.out.print("Type in the number of clients");
int numClients= sc.nextInt();
Hotel h1 = new Hotel(name, numRooms, numClients);
h1.show();
}

How do I sort an array of 12 people into a smaller array of 4 families?

How do I take an array which contains 12 people and their incomes from an infile and sort it into a smaller array of 4 families and their total incomes? This is what I have so far.
public class Assignment7Sasha
{
public static void main(String[] args)throws IOException
{
String lname[] = new String[12];
String fname[] = new String[12];
double income[] = new int[12];
int deductions;
int i;
double taxrate;
double familytax;
double familyincome;
double adjustedfamilyincome;
PrintWriter outfile = null;
outfile = new PrintWriter
(new FileOutputStream("Prog7Results"));//Results are the last names sorted into 4 different families
Scanner infile=new Scanner(new FileInputStream("Prog7FamilyInfo.dat"));
for( i=0;i<12; i++)
{
lname[i] = infile.next();
fname[i] = infile.next();
income[i] = infile.nextInt();
}
for(i=0; i<12; i++)
outfile.println(lname[i] + "\t"+ fname[i] + "\t"+income[i]);
//object is created and the constructor is invoked
Assignment7Sorting nm = new (lname, income, outfile);
nm.sort();
outfile.println("The sorted list of families and their adjusted incomes is:");
for(i=0; i<4; i++)
outfile.println(lname[i]+ " " + adjustedfamilyincome[i] + " " + familytax[i]);
infile.close();
outfile.close();
}
}
Your question is pretty vague, so I will attempt to answer it based on what information you are giving.
You can create a static class to hold the income, last name and other attributes of each family that you may want. You can use an ArrayList to maintain a dynamic list of such objects, and go through the list using an Iterator object.
public class Assignment7Sasha{
private static final class Family{
String lname;
int income;
}
public static void main(String[] args){
//All variable declarations
ArrayList families = new ArrayList<Family>();
//Read into arrays lname, fname and income as you have done
for(int i = 0; i < 12; i++){
boolean exists = false;
Iterator it = families.iterator();
while(it.hasNext()){ //Check if lname[i] already exists in families
Family f = (Family)it.next();
if(f.lname.equals(lname[i])){ //If lname[i] already exists
f.income += income[i];
exists = true;
break;
}
}
if(!exists){ //If lname[i] doesn't exist
Family f = new Family();
f.lname = lname[i];
f.income = income[i];
families.add(f);
}
}
Iterator it = families.iterator();
while(it.hasNext()){
Family f = (Family)it.next();
//Handle each Family object however you want
System.out.println("Family:" + f.lname + " Income:" + f.income);
}
}

Arrays: Comparing one array to another to find averages

Hey I'm trying to calculate the of a quiz by comparing two arrays. The two arrays set up are the correct answers and student answers of a quiz. I'm trying to get it to look like this:
Student Marks Average
Arnie Score: 4 Percentage: 0.8
This is because Arnie has got 4 questions correct out of 5 questions. The answers of the student and the correct answers are found in the text document which I already loaded onto an array on my code. The text document contains a 2D array with Arnie's answers in the form of chars and a 1D array containing the correct answers (also chars). There are more students but I would like some guidance on how to get the average for Arnie so I can do it for the rest of the names on my own.
Here is my code so far with the two arrays set up.
public class workingCode
{
private static String newline = System.getProperty("line.separator");
public static void stuAnsOut(String arg []) throws IOException
{
File studentAns = new File("Ans_Stu.txt");
Scanner stuAns = new Scanner(studentAns);
String stuAnsString[] = new String[6];
char stuAnsArray[][] = new char[3][5];
String[] stuNameArray = new String[3];
for (int i = 0; i<stuAnsString.length;i++)
{
stuAnsString[i]=stuAns.nextLine();
}
for (int i=0,j=0; i<stuAnsArray.length && j<stuAnsString.length;i++, j=j+2)
{
stuNameArray[i] = stuAnsString[j];
}
for (int i=0,j=1; i<stuAnsArray.length && j<stuAnsString.length;i++, j=j+2)
{
stuAnsArray[i] = stuAnsString[j].toUpperCase().toCharArray();
}
System.out.println("Student Answers: ");
System.out.printf("%5s","Name");
for (int i =0; i<1;i++)
{
for (int j =1; j<(stuAnsArray[i].length+1);j++)
{
System.out.printf("%5s",j);
}
}
System.out.printf("%n");
for (int i =0; i<stuAnsArray.length;i++)
{
System.out.printf("%5s",stuNameArray[i]);
for (int j=0;j<stuAnsArray[i].length;j++)
{
System.out.printf("%5s",stuAnsArray[i][j]);
}
System.out.printf("%n");
}
}
public static void corAnsOut(String arg []) throws IOException
{
File correctAns = new File("Ans_Cor.txt");
Scanner corAns = new Scanner(correctAns);
String corAnsString = corAns.next();
char corAnsArray[] = new char[5];
for (int i=0; i<corAnsArray.length;i++)
{
corAnsArray[i] = corAnsString.toUpperCase().charAt(i);
}
System.out.println("Correct Answers: ");
System.out.println(newline);
for (int i =1; i<(corAnsArray.length+1);i++)
{
System.out.printf("%5s",i);
}
System.out.printf("%n");
for (int i =0; i<corAnsArray.length;i++)
{
System.out.printf("%5s",corAnsArray[i]);
}
System.out.printf("%n");
}
}
I am not allowed to use ArrayLists, only Arrays. And please use the array names I already have in my code. Thanks!
Edit: This is what I got so far. But it is giving me an error:
public static void compareInteger(int corAnsArray [], int stuAnsArray[])
{double score =0;
for (int i = 0; i < stuAnsArray.length; i++)
{if(stuAnsArray[i] == corAnsArray[i])
score += 1.0;
}
System.out.println(score/corAnsArray.length);
}
What i would do is create a class called Student
public class Student {
private string studentName;
private float marks;
private float average;
// Getters & all parameter constructor
}
Then change your working class to
public class workingCode
{
private static String newline = System.getProperty("line.separator");
public static void stuAnsOut(String arg []) throws IOException
{
File studentAns = new File("Ans_Stu.txt");
Scanner stuAns = new Scanner(studentAns);
List<Student> students = new ArrayList<Student>();
while(stuAns.hasNext()) {
string parts = stuAns.nextLine().split(" ");
students.add(new Student(parts[0],parts[1],parts[2]))
}
// At this point you have all the students in the List
}
}
Now to calculate avg :
float total = 0;
for(Student s : students) {
total += s.getMarks();
}
System.out.println("avg = " + total/students.size());
or
float total = 0;
for(Student s : students) {
total += s.getAverage();
}
System.out.println("avg = " + total);
Code for comparing arrays (both for INT and String arrays):
public class Compare{
public static void main(String[] args){
double averageInt;
double averageString;
int[] correctInt = {9,8,12,6,3,12,90}; //Correct answers
int[] answerInt = {9,8,4,6,3,12,90}; //Student's answers
String[] correctString = {"A","A","B","C"}; //Correct answers
String[] answerString = {"A","C","B","C"}; //Student's answers
Compare compare = new Compare();
averageInt = compare.compareInteger(correctInt, answerInt);
averageString = compare.compareString(correctString, answerString);
System.out.println(averageInt);
System.out.println(averageString);
}
public double compareInteger(int[] correct, int[] answer){ //Compares the int arrays
double score = 0;
for(int i = 0; i < correct.length; i++){
if(correct[i] == answer[i])
score += 1.0;
}
return score/correct.length; //Returns average
}
public double compareString(String[] correct, String[] answer){ //Compares the String arrays
double score = 0;
for(int i = 0; i < correct.length; i++){
if(correct[i].equals(answer[i]))
score += 1.0;
}
return score/correct.length; //Returns average
}
}
I do not understand the marking system though. If you'd explain it more in-depth, I'd be more than happy to provide you with the code.

How do i return 2 values from a single method

import java.util.Scanner;
public class fmax
{
public static void main(String[] args)
{
int max;
max = maxnum();
System.out.println("The max number is: " + max);
}
public static int maxnum()
{
int max = 0, element = 0;
Scanner keyboard = new Scanner(System.in);
int []fmax = new int[10];
for(int i = 0; i < fmax.length; i++)
{
System.out.print("Enter number " + (i+1) + ":");
fmax[i] = keyboard.nextInt();
if(fmax[i] > max)
{
max = fmax[i];
element = i; //the variable i want to be returned
}
}
return max;
}
}
Okay, I am able to return a max value in this program, however, I would like to return the value of the element/index assigned to the max value that I return. How would i go about doing that?
to return two values pack it into some object and return it ;)
public class ReturnedObject{
private Object val1;
private Object val2;
//getters setters
}
public ReturnedObject yourMethod(){
ReturnedObject returnedObject = new ReturnedObject();
returnedObject.setVal1("yourVal1");
returnedObject.setVal2("yourVal2");
return returnedObject;
}
You can pass the values into arrays/objects. (I am not saying that you can return an array).If you pass array into the method as one of the parameters, the values of the array shall remain. You can access the values from there.
Note: If you find yourself in need of returning more than one value using one method, you should consider re-designing your codes.

Categories