Functions/Methods and Arrays - java

My class has just started learning how to write code in a format with functions and methods, and this is my first attempt at it - I feel like I'm just confusing myself.
The assignment is to create a pool of numbers 1 to a randomly selected number and to store the pool in an array; then print the pool; then a user selects a number from the pool, and the program finds the divisors of that number and stores them in another array that will then be printed.
I am having problems with getting the divisors, storing them in a new array and then printing the array.
import java.util.Scanner;
import java.util.Random;
public class GetDivisors {
public static void main (String[] args){
Scanner read = new Scanner(System.in);
int []pool = new int[100];
int []divisors = new int[100];
int size;
int pick;
int numDivisor;
// Program Heading
printProgramHeading();
// Input and test
size = createPool(pool);
printPool(pool, size);
System.out.println();
System.out.println();
System.out.println("Enter a non-prime value listed in the pool above: ");
pick=read.nextInt();
// Data Processing
numDivisor = getDivisors(pool, divisors, pick);
// Output Section
printDivisors(divisors, size, pick);
} // end main
// Function and Method Specifications
// Name : printProgramHeading
// Description : This method prints the program heading to the monitor in all caps and with a dividing line
// : followed by a blank line.
// Parameters : None.
// Return : None.
public static void printProgramHeading() {
System.out.println("\tGET DIVISORS");
System.out.println(" ************************");
System.out.println();
} // end printHeading
//Name : createPool
//Description : This funtion generates an array of consecutive integers from 1 to a randomly generated
// : number no greater than 100.
//Parameters : An integer array.
//Return : An integer (the randomly generated number), representing the size of the array.
public static int createPool(int[]pool) {
Scanner read = new Scanner(System.in);
Random random = new Random();
int size=0;
size=random.nextInt(100)+1;
pool=new int[size];
return(size);
} // end createPool
//Name : printPool
//Description : This method prints the pool of numbers to the monitor no more than 10 per line.
//Parameters : The pool array, and the size of the pool in that order.
//Return : None.
public static void printPool(int[] pool, int size) {
int index;
int count=0;
for(index=1; index<size; index++){
System.out.print(pool[index]=index);
System.out.print(" ");
count++;
if(count == 10){
System.out.println();
count=0;
} // end if loop
} // end for loop
} // end printPool
//Name : getDivisors
//Description : This funtion stores all the divisors of the user's pick into the divisor array.
//Parameters : The pool array, the divisor array, and the user's pic, in that order.
//Return : The number of divisors found.
public static int getDivisors(int[] pool, int[] divisors, int pick){
int numDivisors = 0;
int index = 0;
for(index=1; index <= pick; index++){
if(pick % index == 0){
numDivisors++;
divisors[index] = index;
} // end if loop
} // end for loop
return(numDivisors);
} // end getDivisors
//Name : printDivisors
//Description : This method prints the contents of the divisors array to the monitor all on one line with
// : a leading label.
//Parameters : The divisor array, an integer representing the number of divisors. and the user's pick
// : in that order.
//Return : None.
public static void printDivisors(int[] divisors, int size, int pick){
int index = 0;
System.out.println("The divisors of " + pick + ": " + divisors[index] + " ");
} // end printDivisors
} // end class
Thank you!

This is obviously a school project. In order for you to learn I don't want to give you the answers but i'll point out your mistakes, so that you can fix your problems.
First in this method createPool:
//Name : createPool
//Description : This funtion generates an array of consecutive integers from 1 to a randomly generated
// : number no greater than 100.
//Parameters : An integer array.
//Return : An integer (the randomly generated number), representing the size of the array.
public static int createPool(int[]pool) {
Scanner read = new Scanner(System.in);
Random random = new Random();
int size=0;
size=random.nextInt(100)+1;
pool=new int[size];
return(size);
} // end createPool
Look closer at the values that are stored in the array.
Second in method printPool:
//Name : printPool
//Description : This method prints the pool of numbers to the monitor no more than 10 per line.
//Parameters : The pool array, and the size of the pool in that order.
//Return : None.
public static void printPool(int[] pool, int size) {
int index;
int count=0;
for(index=1; index<size; index++){
System.out.print(pool[index]=index);
System.out.print(" ");
count++;
if(count == 10){
System.out.println();
count=0;
} // end if loop
} // end for loop
} // end printPool
You are updating the values of the pool. This method should only print the values in the pool. You should be setting the values of the pool in createPool, and printing the values of the pool in printPool.
Next in the getDivisors method
//Name : getDivisors
//Description : This funtion stores all the divisors of the user's pick into the divisor array.
//Parameters : The pool array, the divisor array, and the user's pic, in that order.
//Return : The number of divisors found.
public static int getDivisors(int[] pool, int[] divisors, int pick){
int num = 0;
int divisor = 0;
int numDivisors = 0;
int index = 0;
for(pool[index]=1; pool[index]<=pick; pool[index]){
num = pick % pool[index];
if(num == 0){
divisor = num;
numDivisors++;
divisors= new int[divisor];
} // end if loop
} // end for loop
return(numDivisors);
} // end getDivisors
You have a lot of things wrong with this method. First, re-look at your for loop. I really think you need to learn further about how for loop should operate and when is the best time for use for loops. Your underlying understanding of for loops in flawed. Your logic is right for calculating the divisor, but you have two issues related to this logic. 1) Relook at how you put the new divisor into the divisors array. This is related to the earlier issue of how you use the for loop. Once you solve the for loop problem, this should become more clear 2) What should you store into the divisors array when num == 0 is false? You need to handle this case, right?
Now onto the printDivisors method:
//Name : printDivisors
//Description : This method prints the contents of the divisors array to the monitor all on one line with
// : a leading label.
//Parameters : The divisor array, an integer representing the number of divisors. and the user's pick
// : in that order.
//Return : None.
public static void printDivisors(int[] divisors, int size, int pick){
int index = 0;
System.out.println("The divisors of " + pick + ": " + divisors[index] + " ");
} // end printDivisors
Once again, you really need to understand when and when-not to use a for loop. This method should print out all the values in the divisors array. Currently, this method only prints out one value in the divisors array (the first value, at index 0).
Finally, in the main() function:
public static void main (String[] args){
Scanner read = new Scanner(System.in);
int []pool = new int[100];
int []divisors = new int[100];
int size;
int pick;
int divisor;
// Program Heading
printProgramHeading();
// Input and test
size = createPool(pool);
printPool(pool, size);
System.out.println();
System.out.println();
System.out.println("Enter a non-prime value listed in the pool above: ");
pick=read.nextInt();
// Data Processing
divisor = getDivisors(pool, divisors, pick);
// Output Section
printDivisors(divisors, size, pick);
} // end main
Should int[] pool, and int[] divisors be initialized initially with an arbitrary size of 100? Random numbers like these are usually called "magic numbers". Magic numbers should either be set as a constant with a description, or taken out of the program. Next, you print the header. This seems ok. Then you create the pool, and save the pool size into size, and print the pool with the given size passed into the function. This all seems fine. Next you poll the user for a divisor input, and call the getDivisors function with the user input. Also you save the output into a variable divisor, which represent the size of the divisor array. Now, look at the parameters you pass into printDivisors, something smells fishy here...
These are all of the issues that I see with your code. This should give you plenty of information on how to improve your mistakes. If you have anymore questions please feel free to ask.

Sorry I can't comment your question. Is it ok if you use Collections instead of arrays?
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class GetDivisorsRefactored {
private static Integer[] pool;
private static Scanner read;
public static void main(String[] args) {
// Program Heading
printProgramHeading();
initPool();
System.out.println("Available list: ");
printArray(pool);
read = new Scanner(System.in);
System.out.println();
System.out.println();
System.out.println("Enter a non-prime value listed in the pool above: ");
int pick=read.nextInt();
Integer[] divisors = findDivisors(pick);;
printArray(divisors);
}
private static void printArray(Integer[] someArray) {
int nextRow = 0;
for (int num: someArray){
System.out.printf("%4d,", num);
if (++nextRow > 9){
System.out.println();
nextRow =0;
}
}
}
private static Integer[] findDivisors(int pick) {
List<Integer> divisors = new ArrayList<Integer>();
for (int index = 1; index < pool.length; index++){
if ((pick % pool[index]) == 0){
divisors.add(pool[index]);
}
}
return divisors.toArray(new Integer[divisors.size()]);
}
private static void initPool() {
int size = (int) (Math.random()*100) + 1;
pool = new Integer[size];
for (int index = 0; index < pool.length; index++){
pool[index] = index;
}
}
// Function and Method Specifications
// Name : printProgramHeading
// Description : This method prints the program heading to the monitor in
// all caps and with a dividing line
// : followed by a blank line.
// Parameters : None.
// Return : None.
public static void printProgramHeading() {
System.out.println("\tGET DIVISORS");
System.out.println(" ************************");
System.out.println();
} // end printHeading
}

Related

How to pass method output into an array element?

The basis of my problem is here: https://github.com/experiencethebridge1/primeGap
Bottom line, I want to create an array in which the output of a method will populate the elements of the new array.
This is not homework.
package primenumbermethod;
import java.util.Scanner;
public class PrimeNumberMethod {
public static void main(String[] args) {
System.out.print("How many prime numbers do you want to work with? ");
Scanner input = new Scanner(System.in);
int arraySize = input.nextInt();
// Invoke printPrimeNumbers method
System.out.println("If I can ever get it to work, the number of the "
+ "elements in the array I want to build will be " + arraySize +".");
System.out.println();
printPrimeNumbers(arraySize);
// How can I read parts of a method into elements of an array?
int[] myList = new int[arraySize];
}
public static int printPrimeNumbers(int numberOfPrimes) {
final int NUMBER_OF_PRIMES_PER_LINE = 10; // Display 10 per line
Scanner input = new Scanner(System.in);
System.out.print("What number do you want to start from? ");
int number = input.nextInt();
int count = 0; // Count the number of prime numbers
// Repeatedly find prime numbers
while (count < numberOfPrimes) {
// Print the prime number and increase the count
if (isPrime(number)) {
count++; // Increase the count
if (count % NUMBER_OF_PRIMES_PER_LINE == 0) {
// Print the number and advance to the new line
System.out.printf("%-15d\n", number);
} else {
System.out.printf("%-15d", number);
}
}
number++;
}
return 0;
}
// Method for checking if number is prime
public static boolean isPrime(int number) {
for (int divisor = 2; divisor <= number / 2; divisor++) {
if (number % divisor == 0) {// If true, number is not prime
return false; // Number is not a prime
}
}
return true; // Number is prime
}
}
Tried using global variables, abstraction does not apply (but could).
The main method initiates the program, then traces to method printPrimeNumbers, then into method boolean isPrime. I want to return the output of that method into a new array...
The array size will be defined by the user input <"How many prime numbers do you want to work with? ">, and then <"What number do you want to start with?>
Problem, I can't seem to pass the output of a method into the elements of an array.
Thoughts?
I would suggest you should restructure your code in the following way:
public static void main(String[] args) {
int numberOfPrimes = readIntFromCommandLine...;
int numberToStartWith = readIntFromCommandLine...;
int[] primeNumbers = getPrimeNumbers(numberOfPrimes, numberToStartWith);
// maybe extract this to another method as well
for (int prime : primeNumbers) {
// do whatever you want with prime, e.g. print it - or sum it, or multiply or whatever
}
}
public static int[] getPrimeNumbers(int amount, int from) {
int[] primes = new int[amount];
int count = 0;
/* now put your current prime logic here and whenever you
find a prime set primes[count] = newlyFoundPrime; */
}
public static boolean isPrime(int number) { /* stays the same */ }
It is generally a good idea to only ask for user input at a well defined point in your code, not all over the place. Therefore I placed the two inputs at the front. Another generally good idea is to make every method (maybe except for the main method) only do one thing. Your isPrime is a good example of that. Moving the printing logic out of getPrimeNumbers simplifies that method and lets you handle the printing at another, dedicated place.

Frequency Array and Histogram in Java

I have to make the following program.
Write a program that builds a frequency array for data values in the range 1 to 20 and then prints their histogram. The data is to be read as input from the user. Add the following functions to your program:
a. The getData function takes input from the user and stores the data in an array.
b. The printData function prints the data in the array.
c. The makeFrequency function examines the data in the array, one element at a time, and adds 1 to the corresponding element in a frequency array based on the data value.
d. The makeHistogram function prints out a vertical histogram using asterisks for each occurrence of an element. For example, if there were five value 1s and eight value 2s in the data, it would print
1: *****
2: ********
I managed to make getData function but I can't make the other 3. Any help would be appreciated. Here is my code
import java.util.Scanner;
public class FrequencyArray {
static Scanner scan = new Scanner(System.in);
public void getData() {
System.out.println("Enter the size of array: ");
int nums = scan.nextInt();
int[] a = new int[nums];
for (int i = 1; i < a.length; i++) {
System.out.print("Enter the numbers: " + i + ":");
a[i] = scan.nextInt();
}
}
public void printData() {
getData();
}
public static void main(String[] args) {
FrequencyArray array = new FrequencyArray();
array.getData();
}
}
To print such an array, all you would need is another for-loop - loop from 0 to the array's length, and print both the loop counter's value, and the value stored in the array at that index.
System.out.println(index + ":" + array[index]);
For the histogram, do a similar loop, but for each value of the array, append an asterisk to the current line for however many instances of said number there are.
System.out.print(index);
//from 0 to the amount of this number, call System.out.print("*");
System.out.println();
Use TreeMap to store the number and their frequency in a sorted order once you get the data
then iterate over the TreeMap to print the number followed by the stars denoting the count of the value
public void printData() {
int [] numArray = getData();
Map<Integer,Integer> valueCountMap = new TreeMap();
for(int i=0;i<numArray.length;i++) {
int num = numArray[i];
if(valueCountMap.get(num) == null) {
valueCountMap.put(num,0);
}
int count = valueCountMap.get(num);
valueCountMap.put(num,count+1);
}
for(Map.Entry<Integer,Integer> entry:valueCountMap.entrySet()) {
int num = entry.getKey();
int value = entry.getValue();
System.out.print(num+":");
for(int i=0;i<value;i++) {
System.out.print("*");
}
System.out.print(" ");
}
}
Following assumptions i have made getData must return interger array and you need to print in one line. Following rectification i have done to your code
in getData i = 0 not i = 1

Arrays, arrays in "for" loops

I'm trying to calculate something properly. A user enters an amount of trees they want to plant, and there is a rule that a certain percent of trees die every single year. It says after 7 years the trees are sellable. To find the minimum number of seeds needed, you'd take however many die over the course of 7 years for each tree type, and add that to the initial number the user inputted, right?
Well, this is what I get when i enter 20,40,30 for each tree type respectively:
I get the same number of minimum seeds regardless. I assume this has to do with my index or something in my for loop. I'd just like to know how to properly calculate this.
The other issue: I am trying to format my output properly so that it tabs over for each variable so it doesn't look so ugly the way it does. I tried "\t" but it did nothing. How do I fix this, and the calculations so that each iteration is actually kept track of in the end? should I be using decayRate[i], desiredYield[i] etc instead of desiredYield[index] etc?
public class TreeCalc {
public static void main(String[] args){
//Initializes methods and arrays
String[] treeTypes = new String[] {"Fir", "Pine", "Spruce"};
int[] desiredYield = new int [treeTypes.length];
double[] decayRate = new double[] {0.07, 0.12, 0.08};
desiredYield = getYield(decayRate, desiredYield, treeTypes);
int[] data = getCalculate(decayRate, desiredYield, treeTypes);
printMessage(decayRate, desiredYield, treeTypes);
}
//Asks user to input # of trees for each tree type
public static int[] getYield(double[]decayRate, int[] desiredYield, String[]treeTypes) {
int index= 0;
for(int i=0;i < treeTypes.length;i++) {
try {
desiredYield[index] = Integer.parseInt(JOptionPane.showInputDialog("Please enter your desired yield for: " +treeTypes[i]));
//Catches any non-number input, displays error to user
} catch(NumberFormatException e){
desiredYield[index] = 0;
JOptionPane.showMessageDialog(null, "Error: Please enter your desired yield for "+treeTypes[i]);
}
if (desiredYield[index] <= 0) {
JOptionPane.showMessageDialog(null, "Error: Please enter your desired yield for "+treeTypes[i]);
} else{
index++;
}
}
return desiredYield;
}
//Calculates totals and minimums
public static int[] getCalculate(double[]decayRate, int[]desiredYield, String[]treeTypes){
int totalSeeds =0;
int totalTrees=0;
int minSeeds=0;
int index=0;
//For each iteration of the loop, calculates totals/mins
for(int i = 0; i < treeTypes.length; i++){
minSeeds += (desiredYield[index] * (decayRate[index]*7)) + desiredYield[index];
totalSeeds += minSeeds;
totalTrees += desiredYield[index];
}
return new int[] {totalSeeds, totalTrees, minSeeds};
}
//Prints the totals, minimums, and input from the user
public static void printMessage(double[]decayRate, int[]desiredYield, String[]treeTypes){
//Calls method and stores values within array
int[]data = getCalculate(decayRate, desiredYield, treeTypes);
int totalSeeds = data[0];
int totalTrees = data[1];
int minSeeds = data[2];
//Report displays after user is done entering inputs
String treeReport = "Tree Type | Desired Yield | Minimum Seeds | Total Seeds | Total Trees ";
for(int i=0; i<treeTypes.length; i++){
treeReport += "\n"+treeTypes[i] + " "+desiredYield[i] + " "+minSeeds + " "+totalSeeds + " "+totalTrees;
}
JOptionPane.showMessageDialog(null, treeReport);
}
}
No, your equation for the minimum number of seeds needed is not correct. You need something like M=Y/((1-r)^7) Where r is the proportion of trees that die each year, and Y is the desired yield. You solve for M, the minimum # of seeds.

Java ArrayList: Utilising ArrayList for print message

In my Java program I have an ArrayList. What I want to do is print a number at the bottom that will say 'x amount of people have passed'
System.out.println = ("The amount of people that have more than 40 marks is " + x);
Is it possible to calculate how many numbers of marks will be more than 40 if there are an undetermined amount of marks put in, utilising an ArrayList?
public class test {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ArrayList<Integer> marks = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
// Create a new scanner to use in java
int[] range = { 0,29,39,69,100 };
// A new array is created with the grade boundaries
int[] inRange = new int[boundary.length - 1];
// Indexed from 0 to n-1
int markIn;
// New integer markIn
do {
// This do-while loop calculates the expression after the statements below are exectued at least once
System.out.println("Enter Mark(s):");
// Wait for user input
markIn = input.nextInt();
// markInp value is set as the value entered by user
marks.add(markIn);
for (int a=1 ; a<boundary.length ; a++)
// for loop will take the variable 'a' and compare it with varibale 'boundary', when the condition is satisfied that value of 'a' increments by 1
if (range[a-1] <= markInp && markInp <= range[a]) {
// The boundaries will define the upper and lower limits of the markInp
inRange[a-1]++;
//inRange is incremented by 1
break;
//Exit if
}
} while (markIn <= 100);
// When the mark exceeds 100, the loop is stopped
System.out.println(marks);
input.close();
} // Close the Scanner input
}
You can do something like :
int result = 0;
if(marks != null)
{
Collections.sort(marks);
for(int i=0;i<marks.size();i++)
{
if(marks.get(i) > 40)
{
result = marks.size() - i;
break;
}
}
}
marks is the arraylist and result is desired output.
If the array is already sorted, like you show in your example, then you just have to do a simple search from where you start seeing a particular score, then taking the length of the array and subtracting the position of the element that came from your search.
If the array isn't sorted, sort it and then do the search.

Need help writing a program that finds the highest and second highest number is a series

The program is designed for the user to enter a series of numbers until the user enters the sentinel which i set to the value of 0. After the user enters the sentinel the program is supposed to print the highest number and the second highest number in that list. The trouble I'm having is where I expect the second highest number to be it prints 0 instead.
Is there a more elegant way of solving this problem by using the ?: operator? Is it possible?
import acm.program.*;
public class LargestAndSecondLargest extends ConsoleProgram {
public void run() {
int a = 0;
int b = 0;
while (true) {
int value = readInt(" ?: ");
if (value == SENTINEL) break;
if (value > a) {
a = value;
}
else if (value > b) {
b = value;
}
}
println("the largest value is " + a);
println("the second largest number is" + b);
}
private static final int SENTINEL = 0;
}
There are two issues:
The second comparison is wrong.
When you encounter a new highest number, you need to shift the previous highest number into the second-highest slot. Otherwise the sequence 1, 2, 3 would produce 3 and 1 as the two highest numbers.
else if ( b > value )
The above else if condition should be: -
else if ( value > b )
Else, your b will never get changed, if you are entering only positive numbers, and hence the 2nd largest value will be 0.
Also see 2nd requirement in #NPE's answer that is necessarily required.
insert the values into an array. Sort the array then assign the top two values from the array into your output. if only one value is given depending on requirements set them both to the same value or one to 0.
Here my solution (that you can adapt with your superclass):
public class LargeAndSecondLargest {
public static void main(String[] args) {
new LargeAndSecondLargest().run("1 2 2");
}
public void run(String input) {
final int SENTINEL = 0;
int currVal;
Scanner scanner = new Scanner(input);
List<Integer> numbers = new ArrayList<>();
while (scanner.hasNextInt() && ((currVal = scanner.nextInt()) != SENTINEL)) {
numbers.add(currVal);
}
printFirstAndSecondLargest(numbers);
}
private void printFirstAndSecondLargest(List<Integer> numbers) {
Collections.sort(numbers, Collections.reverseOrder());
System.out.println("the largest value is " + numbers.get(0));
System.out.println("the second largest number is " + numbers.get(1));
}
}

Categories