In this program, you will find a menu with options to perform different functions on an array. This array is taken from a file called "data.txt". The file contains integers, one per line. I would like to create a method to store those integers into an array so I can call that method for when my calculations need to be done. Obviously, I have not included the entire code (it was too long). However, I was hoping that someone could help me with the first problem of computing the average. Right now, the console prints 0 for the average because besides 1, 2, 3 being in the file, the rest of the array is filled with 0's. The average I want would be 2. Any suggestions are welcome. Part of my program is below. Thanks.
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to Calculation Program!\n");
startMenus(sc);
}
private static void startMenus(Scanner sc) throws FileNotFoundException {
while (true) {
System.out.println("(Enter option # and press ENTER)\n");
System.out.println("1. Display the average of the list");
System.out.println("2. Display the number of occurences of a given element in the list");
System.out.println("3. Display the prime numbers in a list");
System.out.println("4. Display the information above in table form");
System.out.println("5. Save the information onto a file in table form");
System.out.println("6. Exit");
int option = sc.nextInt();
sc.nextLine();
switch (option) {
case 1:
System.out.println("You've chosen to compute the average.");
infoMenu1(sc);
break;
case 2:
infoMenu2(sc, sc);
break;
case 3:
infoMenu3(sc);
break;
case 4:
infoMenu4(sc);
break;
case 5:
infoMenu5(sc);
break;
case 6:
System.exit(0);
default:
System.out.println("Unrecognized Option!\n");
}
}
}
private static void infoMenu1(Scanner sc) throws FileNotFoundException {
File file = new File("data.txt");
sc = new Scanner(file);
int[] numbers = new int[100];
int i = 0;
while (sc.hasNextInt()) {
numbers[i] = sc.nextInt();
++i;
}
System.out.println("The average of the numbers in the file is: " + avg(numbers));
}
public static int avg(int[] numbers) {
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
sum = (sum + numbers[i]);
}
return (sum / numbers.length);
}
Just modify your method as follows:
public static int avg(int[] numbers, int len) where len is the actual numbers stored.
In your case you call:
System.out.println("The average of the numbers in the file is: " + avg(numbers, i));
And in your code for average:
for (int i = 0; i < len; i++) {
sum = (sum + numbers[i]);
}
I.e. replace numbers.length with len passed in
And do return (sum / len);
Instead of using a statically-sized array you could use a dynamically-sized List:
import java.util.List;
import java.util.LinkedList;
// . . .
private static void infoMenu1(Scanner sc) throws FileNotFoundException {
File file = new File("data.txt");
sc = new Scanner(file);
List<Integer> numbers = new LinkedList<Integer>();
while (sc.hasNextInt()) {
numbers.add(sc.nextInt());
}
System.out.println("The average of the numbers in the file is: " + avg(numbers));
}
public static int avg(List<Integer> numbers) {
int sum = 0;
for (Integer i : numbers) {
sum += i;
}
return (sum / numbers.size());
}
This has added the benefit of allowing you to read in more than 100 numbers. Since the LinkedList allows you to perform an arbitrary number of add operations, each in constant time, you don't need to know how many numbers (or even an upper-bound on the count) before reading the input.
As kkonrad also mentioned, you may or may not actually want to use a floating-point value for your average. Right now you're doing integer arithmetic, which would say that the average of 1 and 2 is 1. If you want 1.5 instead, you should consider using a double to compute the average:
public static double avg(List<Integer> numbers) {
double sum = 0;
for (Integer i : numbers) {
sum += i;
}
return (sum / numbers.size());
}
I think sum should be a double and double should be the return type of your avg function
Please change your average function in such a way
private static void infoMenu1(Scanner sc) throws FileNotFoundException {
.
.
.
System.out.println("The average of the numbers in the file is: " + avg(numbers,i));
}
public static int avg(int[] numbers,int length) {
int sum = 0;
for (int i = 0; i < length; i++) {
sum = (sum + numbers[i]);
}
return (sum / length);
}
While calling average function pass i (which you counted in infoMenu1 for number of entries in data.txt) as well and use that in loop and dividing the sum. with this your loop will not run for 100 iterations and code of lines also reduced.
Related
I'm trying to create a program that will take a user input, input that data into an dynamic array, and then recursively finds the average. The first part of my code works. This allows the newly created array to be passed to the method.
public static void main(String args[])
{
int i = 0;
int sum = 0;
double runningTotal = 0;
int classSize;
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the class size: ");
classSize = keyboard.nextInt();
int newClassSize[] = new int[classSize];
for (i=0; i < newClassSize.length; i++)
{
System.out.println("Please enter the grade of the user at: " + (i + 1));
newClassSize[i] = keyboard.nextInt();
}
findAverage();
for (i=0; i < newClassSize.length; i++){
sum = sum + newClassSize[i];
}
System.out.println(Arrays.toString(newClassSize));
keyboard.close();
}
}
This is where I'm getting confused and confusing myself however. How would I pass the newly created array to the findAverage() method? I would then need to also have that be saved to an accumulator and then devided. Is there a better way to do this? This is my current findAverage() method but I'm confusing myself on my implementation.
public double findAverage(int classAverage, int baseCase, double runningAverage)
{
runningAverage = 0;
int sum = 0;
if (newClassSize.length - 1 > baseCase)
runningAverage = newClassSize.length;
return findAverage();
System.out.println("The class average is " + classAverage);
}
Hopefully I understood your question correctly but heres how to do it below.
The basic idea is that when the index reaches the length of the array in the
recursive function that's the base case. So all you have to do is add to the sum at each index point in the array, and just keep passing in the updated index and sum into the recursive function.
class Main {
public static void main(String[] args) {
int newClassSize[] = {1,2,3}; // User Input let say
double average = findAverage(newClassSize);
System.out.println(average);
}
public static double findAverage(int[] arr){
// Avoid division by zero error
if (arr.length==0){
return 0;
}
return findAverageHelper(arr,0,0);
}
public static double findAverageHelper(int[] arr, int index,int sum){
if (index==arr.length){ // Base Case
return (double) sum/arr.length;
}
// Increase index and add current value at index to sum
return findAverageHelper(arr,index+1,sum+=arr[index]);
}
}
I am a beginner in Java and I am wondering if there is a way to use one input from the user in more than one method? I am making a program that is supposed to take some inputs (integers) from the user and control the inputs, then calculate the average and lastly count the occurrence of the inputs?
I have one main method + 3 different methods (one calculates the average etc). I have tried a lot of different things, but haven't seemed to understand the point with parameters and how they work.
So this is just a quick overview.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("How many elements do you want to enter");
int value = sc.nextInt(); //Number of how many elements the user want to enter
int[] input = new int[value]; //An array with all the values
}
public int secureInt(int number, int[] input, int value) {
if (!Integer.parseInt(number)) {
System.out.println("Invalid input");
} else {
for (int i = 0; i < value; i++) { //Add all the inputs in the array
input[i] = sc.nextInt();
}
}
public double averageCalculator (int value, int[] in){
double average; // The average
double sum = 0; // The total sum of the inputs
if (int i = a; i < value; i++) {
sum = sum + in[i];
}
average = sum / value;
return average;
}
//Count the occurence of inputs that only occure once
public static int countOccurence(//what parameter should i have here?) {
int count = 0;
}
}
Here is some code that may be helpful to you. The idea is to try to emulate or imitate the style & best practices in this excerpt:
import java.util.Scanner;
public class ArrayFiller {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("How many elements do you want to enter");
int input_element_count = sc.nextInt(); //Number of how many elements the user want to enter
int element_count = input_element_count;
int[] array = new int[element_count]; //An array with all the values
enter_elements_of_array(array, element_count, sc);
double average = averageCalculator(array, element_count);
printArray(array);
System.out.println("The average of the entered numbers is " + average);
}
public static void printArray(int[] array) {
System.out.print("The array you entered is : [");
for (int element : array) {
System.out.print(" " + element + " ");
}
System.out.print("]" + "\n");
}
public static void enter_elements_of_array( int[] array, int element_count, Scanner sc) {
for (int i = 0; i < element_count; i++) { //Add all the inputs in the array
System.out.println("Please enter element " + (i+1) + " of " + element_count + ":");
array[i] = sc.nextInt();
}
}
public static double averageCalculator ( int[] array, int element_count){
double average; // The average
double sum = 0; // The total sum of the inputs
for (int i = 0; i < element_count; i++) {
sum = sum + array[i];
}
average = sum / element_count;
return average;
}
//Count the occurence of inputs that only occur once
public static int countOccurence(int[] array) {
int count = 0;
// algorithm for counting elements with cardinality of 1
return count;
}
}
I am currently taking an intro to java class at my school due to my growing interest in programming.
I am to create a program that takes user input for a min and max integer. I am also to take user input for the size of the array as well as whether or not the user would like both the sorted and unsorted lists printed out.
After I collect this information, I need to generate random values within the given min/max range and sort those values(I had no problem completing these steps).
My code:
//Third Project by John Mitchell
package thirdProject;
//Imported library
import java.util.*;
//First class
public class thirdProject {
//Created scanner and random class as well as variables
public static Scanner scan = new Scanner(System.in);
public static Random rand = new Random();
public static int min, max, rand_num, sum, total, temp, i, j;
public static boolean sorted;
public static int[] values = new int[];
//Allowing for the average output to be of type double
public static double average;
//Main method
public static void main(String[] args) {
//Prompt user to enter minimum value to be sorted
System.out.println("Please enter a minimum value: ");
min = scan.nextInt();
//Prompt user to enter maximum value to be sorted
System.out.println("\nPlease enter a maximum value: ");
max = scan.nextInt();
//Prompt user to enter total number of values to be sorted
System.out.println("\nPlease enter the number of values that you would like sorted: ");
total = scan.nextInt();
//Prompt the user whether or not they would like both lists
System.out.println("\nWould you like to see both the sorted and unsorted lists? Please enter 'True' for yes or 'False' for no.");
sorted = scan.nextBoolean();
//Prints lists that were generated
if (sorted == true) {
gen_random_val();
System.out.println("\nThe unsorted list is: " + Arrays.toString(values) + ".");
sort_values();
System.out.println("\nThe sorted list is: " + Arrays.toString(values) + ".");
} else {
gen_random_val();
sort_values();
System.out.println("\nThe sorted list is: " + Arrays.toString(values) + ".");
}
}
//Second method
public static void gen_random_val() {
//For loop that generates values within the range of values given
for(int i = 0; i < values.length; i++) {
values[i] = rand_num = Math.abs(rand.nextInt(max) % (max - min + 1) + min);
sum = sum + values[i];
average = (sum*1.0) / values.length;
}
}
//Third method
public static void sort_values() {
//For loop that sorts values
for(i=0; i<(total-1); i++) {
for(j=0; j<(total-i-1); j++) {
if(values[j] > values[j+1]) {
temp = values[j];
values[j] = values[j+1];
values[j+1] = temp;
}
}
}
}
}
Currently, the hard codes length of 10 values in the array works fine as I have recycled part of my code from a previous project. I am looking for guidance on how to simply make the size determined by user input.
Thank you.
For example you can do this:
//Prompt user to enter total number of values to be sorted
System.out.println("\nPlease enter the number of values that you would like sorted: ");
total = scan.nextInt();
values = new int[total];
You don't have to give values to variables when you declare them.
I have the code below so far. I know the median is wrong because I've placed numbers in it and what I really want is for the program to extract these from the file on its own since the numbers may change. I am not sure how to have the program get the 2 numbers in order to retrieve and calculate the median. Please help. I am very new to this and it has taken me all day to get this far!
package trials;
import java.util.Scanner;
import java.io.IOException;
import java.io.File;
public class trials2 {
public static void main(String[] args) throws IOException {
// This is a Scanner object that reads from the keyboard
Scanner in = new Scanner(System.in);
// The following is set to find the file
System.out.println("Please enter the name of your data file: ");
String fileName = in.next();
// The file is then to be scanned
Scanner fileToRead = new Scanner(new File(fileName));
// This loop finds the contents within the file
double sum = 0;
int numStudents = 0;
double maxVal = 0, minVal = 0;
boolean bFirstTime = true;
double currVal;
while (fileToRead.hasNext()) {
if (fileToRead.hasNextDouble()) {
numStudents++;
currVal = fileToRead.nextDouble();
// The following will find the maximum and minimum values within the file
if (bFirstTime) {
maxVal = currVal;
minVal = currVal;
bFirstTime = false;
} else {
maxVal = Math.max(maxVal,currVal);
minVal = Math.min(minVal, currVal);
}
sum += currVal;
} else {
fileToRead.next();
}
}
// Prints out comments and results
System.out.println("***Welcome to the Exam Statistics Program!!***");
System.out.println();
System.out.println("Minimum = " + minVal);
System.out.println("Maximum = " + maxVal);
System.out.println("Average score: " + sum/numStudents);
System.out.println();
System.out.println("Number of scores by letter grade: ");
System.out.println();
System.out.println("There are " + numStudents + " scores");
}
}
There are a few steps to doing this.
At the beginning of your program, create an ArrayList<Double> for storing your values in.
Within your main loop, use the list's add method to add each value as you read it.
At the end of your loop, Use Collections.sort to sort your list.
Use the following logic to work out the median.
If the size of the list is zero, then there's no median.
If the size of the list is odd, then the median is the value at position size() / 2 of the list.
If the size of the list is even, then the median is the average of the value at position size() / 2 - 1 and size() / 2 of the list.
I deliberately haven't given you code, because I think you're enjoying learning how to do this for yourself. But feel free to post a comment if you need more detail on any particular step.
Note: Just a practice problem, not for marks.
This is a practice problem given in a first year Java course:
Design and implement an application that reads an arbitrary number of integers, by the user, that are in the range 0 to 50 inclusive, and counts how many occurrences of each are entered. After all the input has been processed, print all of the values (with the number of occurrences) that were entered one or more times.
In addition, write a method that returns no value which would compute the average of the occurrences of all numbers entered by the user.
This is what I have (I have skipped the "average occurrence" part until I clean this up):
import java.util.Scanner;
public class Main
{
public static Scanner scan = new Scanner(System.in);
public static int[] userIntegers() // this method will build the array of integers, stopping when an out-of-range input is given
{
System.out.println("Enter the number of integers to be recorded: ");
int numInts = scan.nextInt();
int[] userArray = new int[numInts];
int i = 0;
while(i < numInts)
{
System.out.println("Enter an integer between 1-50 inclusive: ");
int userInteger = scan.nextInt();
if(isValidInteger(userInteger))
{
userArray[i] = userInteger;
i++;
}
else if(isValidInteger(userInteger) == false)
{
System.out.println("Try again.");
}
}
return userArray;
}
public static void occurrenceOutput(int[] input) // this method will print the occurrence data for a given array
{
int[] occurrenceArray = new int[51];
int j = 0;
while(j < 51) // iterates through all integers from 0 to 50, while the integer in the array is equal to integer j, the corresponding occurance array element increments.
{
for(int eachInteger : input)
{
occurrenceArray[j] = (eachInteger == j)? occurrenceArray[j]+=1: occurrenceArray[j];
}
j++;
}
int k = 0;
for(int eachOccurrence : occurrenceArray) // as long as there is more than one occurrence, the information will be printed.
{
if(eachOccurrence > 1)
{
System.out.println("The integer " + k + " occurrs " + eachOccurrence + " times.");
}
k++;
}
}
public static boolean isValidInteger(int userInput) // checks if a user input is between 0-50 inclusive
{
boolean validInt = (51 >= userInput && userInput >= 0)? true: false;
return validInt;
}
public static void main(String[] args)
{
occurrenceOutput(userIntegers());
}
}
Can someone point me in a more elegant direction?
EDIT: Thanks for the help! This is where I am at now:
import java.util.Scanner;
public class simpleHist
{
public static void main(String[] args)
{
getUserInputAndPrint();
getIntFreqAndPrint(intArray, numberOfInts);
}
private static int numberOfInts;
private static int[] intArray;
private static int[] intFreqArray = new int[51];
public static void getUserInputAndPrint()
{
// The user is prompted to choose the number of integers to enter:
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of Integers: ");
numberOfInts = input.nextInt();
// The array is filled withchInteger = integer; integers ranging from 0-50:
intArray = new int[numberOfInts];
int integer = 0;
int i = 0;
while(i < intArray.length)
{
System.out.println("Enter integer value(s): ");
integer = input.nextInt();
if(integer > 50 || integer < 0)
{
System.out.println("Invalid input. Integer(s) must be between 0-50 (inclusive).");
}
else
{
intArray[i] = integer;
i++;
}
}
// Here the number of integers, as well as all the integers entered are printed:
System.out.println("Integers: " + numberOfInts);
int j = 0;
for(int eachInteger : intArray)
{
System.out.println("Index[" + j + "] : " + eachInteger);
j++;
}
}
public static void getIntFreqAndPrint(int[] intArray, int numberOfInts)
{
// Frequency of each integer is assigned to its corresponding index of intFreqArray:
for(int eachInt : intArray)
{
intFreqArray[eachInt]++;
}
// Average frequency is calculated:
int totalOccurrences = 0;
for(int eachFreq : intFreqArray)
{
totalOccurrences += eachFreq;
}
double averageFrequency = totalOccurrences / numberOfInts;
// Integers occurring more than once are printed:
for(int k = 0; k < intFreqArray.length; k++)
{
if(intFreqArray[k] > 1)
{
System.out.println("Integer " + k + " occurs " + intFreqArray[k] + " times.");
}
}
// Average occurrence of integers entered is printed:
System.out.println("The average occurrence for integers entered is " + averageFrequency);
}
}
You are actually looking for a histogram. You can implement it by using a Map<Integer,Integer>, or since the range of elements is limited to 0-50, you can use an array with 51 elements [0-50], and increase histogram[i] when you read i.
Bonus: understanding this idea, and you have understood the basics of count-sort
To calculate occurences, you can do something like this:
for(int eachInteger : input) {
occurrenceArray[eachInteger]++;
}
This will replace your while loop.