First time working with arrays, trying to create frequency table - java

I can't see where I'm going wrong with this one, I want it to display the frequencies of the survey's result but all I get is zeros, for example if I enter 1,1,2,2,5 I want it to output:
Displaying response frequencies...
1 2
2 2
3 0
4 0
5 1
but instead I get this:
Displaying response frequencies...
1 0
2 0
3 0
4 0
5 0
here is my main method:
import java.util.Scanner;
public class SurveyTester {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("How many people took the survey?");
int numPeople = input.nextInt();
Survey s = new Survey(numPeople);
int nextResponse;
for (int i = 0; i < numPeople; i++)
{
System.out.print("Input the next survey response (values 1-5):");
nextResponse = input.nextInt();
s.addResponse(nextResponse);
}
System.out.println("Displaying all responses...");
s.displayAllResponses();
System.out.println("Displaying response frequencies...");
s.displayResponseFrequencies();
}
}
here is my class:
public class Survey
{
private int numResponses;
private int maxResponses;
private int[] responses;
private int[] frequencies;
private final int NUM_RESPONSES = 5;
public Survey(int nResponses)
{
maxResponses = nResponses;
numResponses = 0;
responses = new int[nResponses];
frequencies = new int[NUM_RESPONSES]; // There are 5 possible responses to the survey
}
public void addResponse(int response)
{
// This method stores the response
// passed in the parameter 'response'
// to the next free space in the array
{
responses[numResponses]= response;
}
numResponses++;
}
public void displayAllResponses()
{
// This method displays on the screen
// all the responses to the survey
for (int i=0; i<maxResponses; i++)
{
System.out.print(responses[i] + " ");
}
System.out.println("");
}
public void calculateResponseFrequencies()
{
// This method calculates the number of
// responses for each possible answer
// to the survey, 1, 2, 3, 4 or 5
// It stores the frequencies in the
// array 'frequencies'
for (int i=1; i<=maxResponses; i++)
{
if (responses[i] == 1)
{
frequencies[1]++;
}
else if (responses[i] == 2)
{
frequencies[2]++;
}
else if (responses[i] == 3)
{
frequencies[3]++;
}
else if (responses[i] == 4)
{
frequencies[4]++;
}
else if (responses[i] == 5)
{
frequencies[5]++;
}
}
}
public void displayResponseFrequencies()
{
// This method displays the response
// frequences for each of the possible
// response, 1, 2, 3, 4 or 5
for (int i=0; i<frequencies.length; i++)
{
System.out.println((i+1) + "\t" + frequencies[i]);
}
}
}

You are not doing anything with your frequencies array. In you your addResponse method, you need to get the appropriate value and increment it. Add a statement like
frequencies[response-1] = frequencies[response-1] + 1;
Note you can do this with 2 arrays, as you are, especially for learning, but a lot of Java developers would use a Map implementation for this sort of thing, where the keys are the entered values and the values are the frequencies. Keeps all the data in one data structure.

public class DuplicatesInArray {
public static void main(String[] args) {
int count = 0;
int[] arr = new int[6];
int[] frequencyArr = new int[6];
arr[0] = 4;
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
arr[4] = 5;
arr[5] = 4;
for(int i = 0;i < arr.length;i++){
frequencyArr[arr[i]] = frequencyArr[arr[i]] + 1;
}
for(int x = 0;x<frequencyArr.length;x++){
if(frequencyArr[x] > 0){
System.out.println(x + " " + frequencyArr[x] + " times." );
}
}
}
}
Default value in an integer array will be zero. We increment it by one for every occurrence.
Example:If integer 4 occurs 2 times,4th index at the frequencyArr is incremented twice.

Related

Summary function not sorting .csv data entirely

I have a .csv that has data that looks like so:
First name Last initial,1/0,1/0,....
It is either a 1 or 0 depending on the persons choice from a txt file that contains 50 pairs of choices.
E.g. Apple
Pear
Dog
Cat
My issue is that my method (classSummary) that keeps count of how many people select the choices only goes halfway and the count is incorrect.
Here is my code as it stands, and any advice would be much appreciated:
public static void classSummary() {
for (Student student : data) {
int[] answers = student.getAnswers();
for (int i = 0; i < answers.length; i++) {
if (answers[i] == 0) {
choices.get(i).setCount(choices.get(i).getCount() + 1);
}
There are two issues in your approach:
You are checking only the case if (answers[i] == 0) you need an else part to handle the case where that is not true, i.e where answers[i] == 1
your answers array is only half the size of your choices list and the ith index in the array holds information about the i * 2 and i * 2 + 1 choices. But at the moment you associate the ith index of answers with the ith index of your choices list.
Change the code in the inner loop of your classSummary method from:
public static void classSummary() {
for (Student student : data) {
int[] answers = student.getAnswers();
for (int i = 0; i < answers.length; i++) {
if (answers[i] == 0) {
choices.get(i).setCount(choices.get(i).getCount() + 1);
}
}
}
}
to
public static void classSummary() {
for (Student student : data) {
int[] answers = student.getAnswers();
for (int i = 0; i < answers.length; i++) {
if (answers[i] == 0) {
choices.get(i * 2).setCount(choices.get(i * 2).getCount() + 1);
} else {
choices.get(i * 2 + 1).setCount(choices.get(i * 2 + 1).getCount() + 1);
}
}
}
}
You could even shorten the code that #Eritrean suggested to:
public static void classSummary() {
for (Student student : data) {
int[] answers = student.getAnswers();
for (int i = 0; i < answers.length; i++) {
int index = i * 2 + answers[i];
choices.get(index).setCount(choices.get(index) + 1);
}
}
}
But you really should validate the inputs of that text file with the answers like:
while (inFile2.hasNextLine()) {
String line = inFile2.nextLine();
String[] x = line.split(",");
String name = x[0];
int[] answers = new int[x.length - 1];
for (int i = 1; i < x.length; i++) {
answers[i - 1] = x[i].trim().equals("0") ? 0 : 1;
}
Student student = new Student(name, answers);
data.add(student);
}
And you could either use a Map<Integer> instead of the ArrayList<Choices> (this means you would not need to implement the whole Choices class). In that case you either use a HashMap if the order of choices does not matter in the result, or a LinkedHashMap if the order of choices shall be kept in the order they appear in the input file.
Or you implement a method increment in your Choices class to improve the readability of your code:
static class Choices {
// ... existing parts go here
void increment() {
count++;
}
}
Instead of choices.get(index).setCount(choices.get(index) + 1); you would then only write choices.get(index).increment();

Modify the java program so that it works for the numbers in range between -25 and 25

I've started learning java some time ago. I'm reading through the Java Foundations book and doing exercises from the book to practice.
Just come across this one "Modify the java program so that it works for the numbers in the range between -25 and 25." and I wonder if you have any different solutions to it or is it really that simple? :)
Here's the original code:
public class BasicArray
{
public static void main(String[] args)
{
final int LIMIT = 15;
final int MULTIPLE = 10;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++)
list[index] = index * MULTIPLE;
list[5] = 999; // change one array value
// Print the array values
for(int value : list)
System.out.println(value + "");
}
}
And here's my solution to it:
public class BasicArray
{
public static void main(String[] args)
{
final int LIMIT = 51;
final int MULTIPLE = 1;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++)
list[index] = (index - 25) * MULTIPLE;
list[5] = 999; // change one array value
// Print the array values
for(int value : list)
System.out.println(value + "");
}
}
Yes, basically it's really simple exercise.
Regarding to your solution we actually don't need MULTIPLE in code.
public class BasicArray {
public static void main(String[] args) {
final int LIMIT = 51;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++) {
list[index] = (index - 25);
}
list[5] = 999; // change one array value
// Print the array values
for(int value : list) {
System.out.println(value + "");
}
}
}
If you are ready for a bit of advanced java, you can try following:
public class BasicArray {
public static void main(String[] args) {
IntStream.rangeClosed(-25, 25)
.forEach(System.out::println);
}
}
Or this if you need to replace one value:
public class BasicArray {
public static void main(String[] args) {
IntStream.rangeClosed(-25, 25)
.forEach(i -> {
if (i == -20) { // change one array value
System.out.println(999);
} else {
System.out.println(i);
}
});
}
}

Changing one row in 2D ArrayList in java changes all the rows

I want to book one seat in a cinema hall according to input but when I am trying to do that it changes all the rows.
Booked seat is denoted by 'B'.
Method that changes the state of cinema hall:
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
Input and output:
Enter the number of rows:
> 7
Enter the number of seats in each row:
> 8
Cinema:
1 2 3 4 5 6 7 8
1 S S S S S S S S
2 S S S S S S S S
3 S S S S S S S S
4 S S S S S S S S
5 S S S S S S S S
6 S S S S S S S S
7 S S S S S S S S
Enter a row number:
> 2
Enter a seat number in that row:
> 4
Cinema:
1 2 3 4 5 6 7 8
1 S S S B S S S S
2 S S S B S S S S
3 S S S B S S S S
4 S S S B S S S S
5 S S S B S S S S
6 S S S B S S S S
7 S S S B S S S S
whole code:
package cinema;
import java.util.*;
public class Cinema {
private final int rows;
private final int seats;
private final List<List<Character>> seatsArrangement = new ArrayList<>();
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
public int calculateProfit() {
if (this.rows * this.seats <= 60) {
return this.rows * this.seats * 10;
} else {
return (int) ((Math.floor(this.rows / 2.0) * 10 + (this.rows - Math.floor(this.rows / 2.0)) * 8) * this.seats);
}
}
public void showSeatsArrangement() {
System.out.print("Cinema:\n ");
int i = 1;
while (i <= this.seats) {
System.out.printf("%d ", i++);
}
i = 1;
for (var row : this.seatsArrangement) {
System.out.print("\n" + i + " ");
for (var seat : row) {
System.out.printf("%c ", seat);
}
++i;
}
}
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of rows:");
int rows = sc.nextInt();
System.out.println("Enter the number of seats in each row:");
int seats = sc.nextInt();
Cinema cinema = new Cinema(rows, seats);
cinema.showSeatsArrangement();
System.out.println("\nEnter a row number:");
int row = sc.nextInt();
System.out.println("Enter a seat number in that row:");
int seat = sc.nextInt();
cinema.bookSeat(row, seat);
cinema.showSeatsArrangement();
}
}
Each element of your seatsArrangement array is the same ArrayList. You're adding the same ArrayList, rowArrangement, to seatsArrangement.
To fix this create a copies of rowArrangement in the second while loop.
e.g.
while (rows-- != 0) {
List<Integer> tmp = new ArrayList<>(rowArrangement);
seatsArrangement.add(tmp);
}
Thanks #MCI for your help it was a silly mistake.
made few changes in constructor:
original version:
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
Working version:
public Cinema(int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(new ArrayList<>(rowArrangement));
}
}
But for some reason rowArrangment.clone() is not working, getting this error
'clone()' has protected access in 'java.lang.Object'
This solved the issue but I have no idea why?
((ArrayList) rowArrangement).clone();
EDIT: Reason why we need to explicitly cast rowArrangment is because clone() method is integral property of ArrayList and since I used List to refer rowArrangement so I can not call clone() method directly on it because upcasting does not support to access methods of subclass.

Mean, Median, and Mode - Newb - Java

We had a lab in Comsci I couldn't figure out. I did a lot of research on this site and others for help but they were over my head. What threw me off were the arrays. Anyway, thanks in advance. I already got my grade, just want to know how to do this :D
PS: I got mean, I just couldn't find the even numbered median and by mode I just gave up.
import java.util.Arrays;
import java.util.Random;
public class TextLab06st
{
public static void main(String args[])
{
System.out.println("\nTextLab06\n");
System.out.print("Enter the quantity of random numbers ===>> ");
int listSize = Expo.enterInt();
System.out.println();
Statistics intList = new Statistics(listSize);
intList.randomize();
intList.computeMean();
intList.computeMedian();
intList.computeMode();
intList.displayStats();
System.out.println();
}
}
class Statistics
{
private int list[]; // the actual array of integers
private int size; // user-entered number of integers in the array
private double mean;
private double median;
private int mode;
public Statistics(int s)
{
size = s;
list = new int[size];
mean = median = mode = 0;
}
public void randomize()
{
Random rand = new Random(12345);
for (int k = 0; k < size; k++)
list[k] = rand.nextInt(31) + 1; // range of 1..31
}
public void computeMean()
{
double total=0;
for (int f = 0; f < size; f++)
{
total = total + list[f];
}
mean = total / size;
}
public void computeMedian()
{
int total2 = 0;
Arrays.sort(list);
if (size / 2 == 1)
{
// total2 =
}
else
{
total2 = size / 2;
median = list[total2];
}
}
public void computeMode()
{
// precondition: The list array has exactly 1 mode.
}
public void displayStats()
{
System.out.println(Arrays.toString(list));
System.out.println();
System.out.println("Mean: " + mean);
System.out.println("Median: " + median);
System.out.println("Mode: " + mode);
}
}
Here are two implementations for your median() and mode() methods:
public void computeMedian() {
Arrays.sort(list);
if ( (list.size & 1) == 0 ) {
// even: take the average of the two middle elements
median = (list[(size/2)-1] + list[(size/2)]) / 2;
} else {
// odd: take the middle element
median = list[size/2];
}
}
public void computeMode() {
// precondition: The list array has exactly 1 mode.
Map<Integer, Integer> values = new HashMap<Integer, Integer>();
for (int i=0; i < list.size; ++i) {
if (values.get(list[i]) == null) {
values.put(list[i], 1);
} else {
values.put(list[i], values.get(list[i])+1);
}
}
int greatestTotal = 0;
// iterate over the Map and find element with greatest occurrence
Iterator it = values.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if (pair.getValue() > greatestTotal) {
mode = pair.getKey();
greatestTotal = pair.getValue();
}
it.remove();
}
}

How to fill a multidimensional array dependant on variables

The program I am working on is a simple shipping program. What I am having difficulty with is populating a multidimensional array factoring in certain variables.
Example
320 items need to be shipped out to 1 receiver using different box sizes.
XL can hold 50 items
LG can hold 20 items
MD can hold 5 items
SM can hold 1 items
Use the least number of boxes so far.
Code
This is my code so far.
import java.util.Scanner;
public class Shipping {
public static void main(String [] args) {
Scanner kbd = new Scanner(System.in);
final int EXTRA_LARGE = 50;
final int LARGE = 20;
final int MEDIUM = 5;
final int SMALL = 1;
String sBusinessName = "";
int iNumberOfGPS = 0;
int iShipmentCount = 0;
displayHeading(kbd);
iShipmentCount = enterShipments(kbd);
int[][] ai_NumberOfShipments = new int [iShipmentCount][4];
String[] as_BusinessNames = new String [iShipmentCount];
for (int iStepper = 0; iStepper < iShipmentCount; iStepper++) {
sBusinessName = varifyBusinessName(kbd);
as_BusinessNames[iStepper] = sBusinessName;
iNumberOfGPS = varifyGPS(kbd);
calculateBoxes(ai_NumberOfShipments[iStepper],iNumberOfGPS, EXTRA_LARGE, LARGE, MEDIUM, SMALL);
}
//showArray(as_BusinessNames);
}
public static void displayHeading(Scanner kbd) {
System.out.println("Red River Electronics");
System.out.println("Shipping System");
System.out.println("---------------");
return;
}
public static int enterShipments(Scanner kbd) {
int iShipmentCount = 0;
boolean bError = false;
do {
bError = false;
System.out.print("How many shipments to enter? ");
iShipmentCount = Integer.parseInt(kbd.nextLine());
if (iShipmentCount < 1) {
System.out.println("\n**Error** - Invalid number of shipments\n");
bError = true;
}
} while (bError == true);
return iShipmentCount;
}
public static String varifyBusinessName(Scanner kbd) {
String sBusinessName = "", sValidName = "";
do {
System.out.print("Business Name: ");
sBusinessName = kbd.nextLine();
if (sBusinessName.length() == 0) {
System.out.println("");
System.out.println("**Error** - Name is required\n");
} else if (sBusinessName.length() >= 1) {
sValidName = sBusinessName;
}
} while (sValidName == "");
return sValidName;
}
public static int varifyGPS(Scanner kbd) {
int iCheckGPS = 0;
int iValidGPS = 0;
do {
System.out.print("Enter the number of GPS receivers to ship: ");
iCheckGPS = Integer.parseInt(kbd.nextLine());
if (iCheckGPS < 1) {
System.out.println("\n**Error** - Invalid number of shipments\n");
} else if (iCheckGPS >= 1) {
iValidGPS = iCheckGPS;
}
} while(iCheckGPS < 1);
return iValidGPS;
}
public static void calculateBoxes(int[] ai_ToFill, int iNumberOfGPS) {
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++)
}
//public static void showArray( String[] ai_ToShow) {
// for (int iStepper = 0; iStepper < ai_ToShow.length; iStepper++) {
// System.out.println("Integer at position " + iStepper + " is " + ai_ToShow[iStepper]);
// }
//}
}
Change your definition of calculateBoxes() to also take an array that represents the volume of each of the boxes (in your case this will be {50, 20, 5, 1}:
public static void calculateBoxes(int[] ai_ToFill, int[] boxVolumes, int iNumberOfGPS) {
// for each box size
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++) {
// while the remaining items to pack is greater than the current box size
while(iNumberOfGPS >= boxVolumes[iStepper]) {
// increment the current box type
ai_ToFill[iStepper]++;
// subtract the items that just got packed
iNumberOfGPS -= boxVolumes[iStepper];
}
}
}
Another way of calculating this (using / and % instead of a while loop) would be:
public static void calculateBoxes(int[] ai_ToFill, int[] boxVolumes, int iNumberOfGPS) {
// for each box size
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++) {
if(iNumberOfGPS >= boxVolumes[iStepper]) {
// calculate the number of boxes that could be filled by the items
ai_ToFill[iStepper] = iNumberOfGPS/boxVolumes[iStepper];
// reset the count of items to the remainder
iNumberOfGPS = iNumberOfGPS%boxVolumes[iStepper];
}
}
}

Categories

Resources