Arraylist, do while loop and calling a method - java

I need to create an array list to save the value of resistors entered by user. Then I need to ask user which type of method to calculate his answer with, then return back answer. The do while loop needs to keep asking for resistors values until user enter the number zero. The calculations have to be pulled from a class Resistance to Main.
**CLASS***
import java.util.ArrayList;
public class Resistance {
/**
* Holds an object type.
*/
public int userChoice;
ArrayList<Double> resistor = new ArrayList<Double>();
/**
*Chooses which process follows next.
*#return circuitType
*/
public final double calculateResistance() {
if (userChoice == 1) {
return calculateSeriesResistance();
} else {
return calculaParallelResistance();
}
}
/**Returns object of parallel circuit.
*
* #return 1 / runningResistance.
*/
public double calculaParallelResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.lenght; ++index) {
runningResistance = runningResistance
+ +1 / resistor.lenght;
}
return 1 / runningResistance;
}
/**Returns object of series circuit.
*
* #return runningResistance.
*/
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.length; ++index) {
runningResistance = runningResistance + resistor[index];
}
return runningResistance;
}
}
***MAIN********
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
/**
* Makes a Constant.
*/
public final static int DONE = 0;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_SERIES = 1;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_PARALLEL = 2;
public static void main(final String[] args) {
// TODO Auto-generated method stub
DecimalFormat f = new DecimalFormat("##.00");
Resistance myRes = new Resistance();
Scanner keyboard = new Scanner(System.in);
//Display Purpose
System.out.println("\nThis program will calculate "
+ "the resistance of a Parallel or Series "
+ "Circuit\n");
//Display instructions
System.out.println("Please enter the value of your "
+ "resistors separately, when done press 0 (zero)");
int n = 0;
do {
System.out.println("Enter Resistor #" + ++n);
myRes.resistor.add(keyboard.nextDouble());
} while (myRes.resistor > 0);
// Ask Which Method To Use,
do {
System.out.println("\nEnter 1 to calculate "
+ "a Series Circuit "
+ "or 2 for a Parallel Circuit");
myRes.userChoice = keyboard.nextInt();
// Ask user again in case he enters something else
} while (myRes.userChoice != USER_CHOICE_PARALLEL
&& myRes.userChoice != USER_CHOICE_SERIES);
//Output the total resistance
System.out.printf("\nThe Total Resistance is "
+ f.format(myRes.calculateResistance()));
}
}

As said, there are few isues with your code, let's break it down step by step.
First, ArrayList doesn't have a field called length, you want to use size() instead.
Next, your method of calculating parallel resistance is wrong. You are not iterating over your resistors, instead you're using number of resistors to calculate. The correct formula is:
1 / Rtotal = 1 / R1 + 1 / R1 + 1 / R3 + ...
Change your code to:
public double calculaParallelResistance() {
double runningResistance = 0;
//use size() instead of length, which doesn't exist in ArrayList
for (int index = 0; index < resistor.size(); index++) {
//also, iterate over each resistor's value, and to get it,
//use...err, get() method :)
runningResistance += (1 / resistor.get(index));
}
return 1 / runningResistance;
}
Your method calculateSeriesResistance() also has an issue: you can't access object by using array notation, as in resistance[index]. Use get() method, so the correct code is:
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.size(); index++) {
runningResistance += resistor.get(index);
}
return runningResistance;
}
Now, to the main method. Your first 'do' loop is checking against number of resistors in your ArrayList, not against 0 value entered by user. You could use while loop instead and break when 0 entered:
//holds current resistor's value
Double val;
while(true) {
System.out.println("Enter Resistor #" + ++n);
val = keyboard.nextDouble();
//only add if higher than 0
if (val > 0.0) {
myRes.resistor.add(val);
}
//0 entered, so finish the loop
else break;
}

Related

List of divisors of a number

it's my first post so DO stomp me if I wrote something stupid.
I've just started IT classes, and today on "while" loops class my tutor gave us the following homework:
Write a program which reads a natural number n and displays in one graphical box all its divisors from the interval [2; n-1].
So far I came up with a code that works but the result is a bit wrong:
import java.util.Arrays;
import javax.swing.JOptionPane;
public class Divisors {
public static void main(String[] args) {
String n = JOptionPane.showInputDialog(null, "Enter a natural number");
Integer i = Integer.parseInt(n);
int d = i - 1;
int x = 2;
int[] dvr = new int[i]; // [i] because bigger numbers need more iterations
while (x >= 2 && x <= d) {
double y = i % x;
if (y == 0) {
dvr[x] = x;
x = x + 1;
} else {
x = x + 1;
}
}
JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.toString(dvr));
}
}
The problem is that the loop fills the array with a lot of zeroes, and the screenshot of tutor's results shows a window listing only the divisors.
I tried to do this with ArrayList, but that's black magic for me right now and my tutor didn't teach us yet how to use anything beyond stuff used in my code anyway.
Any help highly appreciated.
The main problem you're having is that you're going to have an unknown number of values you want to print, but you're using an array to store them, and arrays have a fixed size. Since you have an array of int, it's going to be entirely populated with the default value of zero.
Ideally, you'd only print the first bunch of non-zero values of your array, but you're storing the divisors scattered throughout your array.
dvr[x] = x; stores each value at an index of that value, when really you should just store each new value into the next open spot in the array.
Create a separate index variable, and store each value using it instead:
int index = 0;
while (x >= 2 && x <= d) {
...
if (y == 0) {
dvr[index++] = x;
...
Then when your main loop is done, you can create a new "display array" that holds only the divisors, and not the zeros. At this point, index tells you exactly how large it needs to be:
int[] display = Arrays.copyOf(dvr, index);
JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.toString(display));
In Java the default value of an int is zero. So that is why you see a lot of zeros.
Since you define the size of the array to be i which is more than what is required as the no of divisors would always be less than i.
So instead of printing the entire array you should only print it up to the total no of divisors for which you should a separate variable instead of using x.
Here is the modified version where I am using a separate index variable to keep track of number of divisors which start from 0. In the end you can just print the array up to the index
import java.util.Arrays;
import javax.swing.JOptionPane;
public class Divisors {
public static void main(String[] args) {
String n = JOptionPane.showInputDialog(null, "Enter a natural number");
Integer i = Integer.parseInt(n);
int d = i - 1;
int index = 0;
int x=2;
int[] dvr = new int[i]; // [i] because bigger numbers need more iterations
while (x >= 2 && x <= d) {
double y = i % x;
if (y == 0) {
dvr[index] = x;
x = x + 1;
index= index + 1;
} else {
x = x + 1;
}
}
JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.copyOfRange(drv, 0, index));
}
}
Set datastructure avoids duplicates, you can use that to overcome the problem of duplicate divisors getting added into the data structure.
import java.util.*;
import javax.swing.JOptionPane;
public class Divisors {
public static void main(String[] args) {
String n = JOptionPane.showInputDialog(null, "Enter a natural number");
Integer i = Integer.parseInt(n);
int d = i - 1;
int x = 2;
Set<Integer> divisors = new HashSet<>();
while (x >= 2 && x <= d) {
double y = i % x;
if (y == 0) {
divisors.add(x);
x = x + 1;
} else {
x = x + 1;
}
}
List<Integer> l = new ArrayList<>(divisors);
JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + l);
}
}
Use ArrayList to create Dynamic Array.
Below Code will help you.
Things to change In your Program.
import java.util.*;
take an ArrayList varible
call toString method on Arraylist Object
import java.util.*;
import javax.swing.JOptionPane;
public class NewClass3 {
public static void main(String[] args) {
String n = JOptionPane.showInputDialog(null, "Enter a natural number");
Integer i = Integer.parseInt(n);
int d = i - 1;
int x = 2;
List<Integer> dvr = new ArrayList<>();
while (x >= 2 && x <= d) {
double y = i % x;
if (y == 0) {
dvr.add(x);
x=x+1;
} else {
x = x + 1;
}
}
JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + dvr.toString());
}
}

Calculate e^x without inbuilt functions in Java

I am a beginner in Java and currently going through the "how to think like a computer scientist" beginners book. I am stuck with a problem in the iteration chapter. Could anyone please point me in the right direction?
When I use math.exp, I get an answer that is completely different from the answer my code obtains.
Note, it's not homework.
Here's the question:
One way to calculate ex is to use the infinite series expansion
ex = 1 + x + x2 /2! + x3/3! + x4/4! +...
If the loop variable is named i, then the ith term is xi/i!.
Write a method called myexp that adds up the first n terms of this
series.
So here's the code:
public class InfiniteExpansion {
public static void main(String[] args){
Scanner infinite = new Scanner(System.in);
System.out.println("what is the value of X?");
double x = infinite.nextDouble();
System.out.println("what is the power?");
int power = infinite.nextInt();
System.out.println(Math.exp(power));//for comparison
System.out.println("the final value of series is: "+myExp(x, power));
}
public static double myExp(double myX, double myPower){
double firstResult = myX;
double denom = 1;
double sum =myX;
for(int count =1;count<myPower;count++){
firstResult = firstResult*myX;//handles the numerator
denom = denom*(denom+1);//handles the denominator
firstResult = firstResult/denom;//handles the segment
sum =sum+firstResult;// adds up the different segments
}
return (sum+1);//gets the final result
}
}
The assignment denom = denom*(denom+1) is going to give a sequence as follows: 1, 1*2=2, 2*3=6, 6*7=42, 42*43=...
But you want denom = denom*count.
Let's say in general we just want to print the first n factorials starting with 1!: 1!, 2!, 3!, ..., n!. At the kth term, we take the k-1th term and multiply by k. That would be computing k! recursively on the previous term. Concrete examples: 4! is 3! times 4, 6! is 5! times 6.
In code, we have
var n = 7;
var a = 1;
for (int i = 1; i <= n; i++ ) {
a = a*i; // Here's the recursion mentioned above.
System.out.println(i+'! is '+a);
}
Try running the above and compare to see what you get with running the following:
var n = 7;
var a = 1;
for (int i = 1; i <= n; i++ ) {
a = a*(a+1);
System.out.println('Is '+i+'! equal to '+a+'?');
}
There are several errors here:
firstResult should start from 1, so that it goes 1+x+x^2 instead of 1+x^2+x^3
As timctran stated you are not calculating the factorial in a correct way.
To wrap up you can simplify your operations to:
firstResult = firstResult * myX / (count+1);
sum += firstResult;
Edit:
- I ran the code and saw that Math.exp(power) is printed instead of Math.exp(x)
- My first item is wrong since sum is initialized to myX.
Why make it complicated? I tried a solution and it looks like this:
//One way to calculate ex is to use the infinite series expansion
//ex = 1 + x + x2 /2! + x3/3! + x4/4! +...
//If the loop variable is named i, then the ith term is xi/i!.
//
//Write a method called myexp that adds up the first n terms of this series.
import java.util.Scanner;
public class InfiniteExpansion2 {
public static void main(String[] args) {
Scanner infinite = new Scanner(System.in);
System.out.println("what is the value of X?");
double x = infinite.nextDouble();
System.out.println("what is the value of I?"); // !
int power = infinite.nextInt();
System.out.println(Math.exp(power));//for comparison
System.out.println("the final value of series is: " + myCalc(x, power));
}
public static double fac(double myI) {
if (myI > 1) {
return myI * fac(myI - 1);
} else {
return 1;
}
}
public static double exp(double myX, double myE) {
double result;
if (myE == 0) {
result = 1;
} else {
result = myX;
}
for (int i = 1; i < myE; i++) {
result *= myX;
}
return result;
}
public static double myCalc(double myX, double myI) {
double sum = 0;
for (int i = 0; i <= myI; i++) { // x^0 is 1
sum += (exp(myX, i) / fac(i));
}
return sum;
}
}
If you want to think like an engineer, I'd do it like this:
keep it simple
break it into pieces
stick closely to the task (like I named the var myI, not myPower - seems clearer to me, for a start - that way you won't get confused)
I hope you like it!
I tried a solution and it looks like this:
public class Fact {
public int facto(int n){
if(n==0)
return 1;
else
return n*facto(n-1);
}
}
}
import java.util.Scanner;
public class Ex {
public static void main(String[] args){
Fact myexp=new Fact();
Scanner input=new Scanner(System.in);
int n=1;
double e=1,i=0,x;
int j=1;
System.out.println("Enter n: ");
n=input.nextInt();
System.out.println("Enter x: ");
x=input.nextDouble();
while(j<=n)
{
int a=myexp.facto(j);
double y=Math.pow(x,j)/(double)a;
i=i+y;
++j;
}
e=e+i;
System.out.println("e^x= "+ e);
}
}

Project Euler p14, stackoverflowerror java (in bluej)

I'm working on euler problem 14 (http://projecteuler.net/problem=14). I've tried to tackle it by having a method which runs through the collatz equations, and returns the number of steps taken. If it's higher then the current record it overwrites it, otherwise it moves on to the next integer. It was giving stack overflow errors so I added the system.out.println messages to try and identify where it was stalling, and currently it dies whenever it reaches 5200~, I'm confused as to why, because as far as i can tell no values encountered at this point should go over the int limit, and the error persisted even if i changed "numberStorage" from int to long.
Here is my current code:
/**
* Write a description of class calculator here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Calculator
{
// instance variables - replace the example below with your own
private int x;
private int startingNumber = 1;
private int stepCount;
private int numberStorage;
private int currentRecordStart;
private int currentRecordSteps = 0;
/**
* a string and int value to track multiple starting numbers with the same number of steps
*/
private String tieNote = "no ties";
private int multiTie = 0;
/**
* Constructor for objects of class calculator
*/
public Calculator()
{
x = 0;
}
/**
* begins function
*/
public void initiater()
{
numberStorage = 0;
stepCount = 0;
startingNumber = 1;
currentRecordStart = 1;
currentRecordSteps = 0;
stepCount = 0;
recordHolder(1,1);
}
/**
* starts next rotation
*/
public void steprunner()
{
++startingNumber;
System.out.println("starting rotation " + startingNumber + " current record " + currentRecordSteps);
stepCount = 0;
numberStorage = 0;
recordHolder(startingNumber, collatzSequence(startingNumber));
}
/**
* Runs collatz sequence and updates a variable with the number of steps.
*/
public int collatzSequence(int N)
{
numberStorage = 0;
numberStorage = N;
if (N == 1)
{
return stepCount;
}
else if ( (N & 1) == 0)
{
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
else if ( (N & 1) != 0)
{
numberStorage = 3 * numberStorage + 1;
++stepCount;
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
return stepCount;
}
/**
* stores record and starts next cycle
*/
public void recordHolder(int startingnumber, int stepcount)
{
if (startingNumber <= 999999)
{
if (stepcount > currentRecordSteps)
{
currentRecordSteps = stepcount;
currentRecordStart = startingnumber;
tieNote = "no ties";
multiTie = 0;
System.out.println("a tie occured!");
}
else if (stepcount == currentRecordSteps)
{
tieNote = ("starting number " + startingnumber + " also had " + stepcount + "steps");
++multiTie;
System.out.println("a secondary tie occured!");
}
steprunner();
}
if (startingNumber == 999999)
{
simulationEnder();
}
}
/**
* ends simulation
*/
public void simulationEnder()
{
System.out.println("the number with the highest number of steps was " + currentRecordStart +
" with " + currentRecordSteps + " steps!");
}
}
I'm not going to read your code. But I can show you a solution, written in pseudocode, that is simple and quick:
function euler14(n):
cs := makeArray(1..n)
maxX, maxLen, cs[1] := 1, 1, 1
for k from 2 to n
c, s := 0, k
while k <= s
if s % 2 == 0
s := s / 2
else
s := 3 * s + 1
c := c + 1
cs[k] := cs[s] + c
if maxLen < xs[k]
maxX, maxLen := k, cs[k]
return maxX
The trick is to calculate and save the values of the lengths of the collatz chain, in order starting from 1; then, if a future sequence drops below its starting point, calculation stops in favor of a simple lookup. Here the cs array is the cache, k is the index of the chain that is currently being computed, s is the current item in the chain, and c is the current length of the chain. Computing euler14(1000000) should take no more than a second or two.

Hill Climbing Code - Random Mutation

This code should compare two fitnesses, use the best one to find the solution and then it uses the best one in the next iteration. However the problem I get is that it is just using the newest fitness regardless of whether it is bigger or smaller. Can anyone help me spot if there are any mistakes in my code, thanks!
This was a little tricky to explain, so if anyone needs more clarification please ask and I'll post up my entire project, though I believe that the error has something to do with this small section of code:
public static ScalesSolution RMHC(ArrayList<Double> weights, int n, int iter) {
ScalesSolution sol = new ScalesSolution(n);
ScalesSolution oldSol = new ScalesSolution(sol.GetSol());
for (int i = 0; i < iter; i++) {
System.out.println("Iteration number: " + i);
System.out.println("Old Solution : ");
oldSol.println();
double f = oldSol.ScalesFitness(weights);
System.out.println("Old Fitness: ");
System.out.println(f);
// the new solution after copying the string from scalesolution
sol.SmallChange();
System.out.println("New Solution : ");
sol.println();
double f1 = sol.ScalesFitness(weights);
System.out.println("New Fitness: ");
System.out.println(f1);
if (oldSol.ScalesFitness(weights) > sol.ScalesFitness(weights)) {
oldSol = new ScalesSolution(sol.GetSol());
}
}
return (oldSol);
}
Here is SmallChange:
public void SmallChange() {
int n = scasol.length();
Random rand = new Random();
int p = (rand.nextInt(n));
String x;
x = scasol.substring(0, p);
if (scasol.charAt(p) == '0') {
x += '1';
} else {
x += '0';
}
x += scasol.substring(p + 1, n);
scasol = x;
}
Here is ScalesFitness and ScalesSolution:
public ScalesSolution(int n) {
scasol = RandomBinaryString(n);
}
// This is the fitness function for the Scales problem
// This function returns -1 if the number of weights is less than the size of the current solution
// Exercise 3
public static double ScalesFitness(ArrayList<Double> weights) {
int n = scasol.length(); // Assigns the length of scasol to n
double lhs = 0.0; // Initialises lhs to 0.0, type double
double rhs = 0.0; // Initialises rhs to 0.0, type double
if (n > weights.size()) // If statement, compares n and weight size
return (-1); // Returns -1 when the if statement is true
// Code goes here
for (int i = 0; i < n; i++) { // For loop which goes from i=0 to n
if (scasol.charAt(i) == '0') { // If statement which checks if the character at position i is equal to a 0
lhs += weights.get(i); // Adds weight at position i to lhs
} else { // If the character in position i is not a 0 do the following
rhs += weights.get(i); // Adds the weight at position i to rhs
}
}
return (Math.abs(lhs - rhs)); // Calculates the absolute value of lhs-rhs and returns the value
}

How can I get the maximum and minimum score of multiple entries

I am creating a program where I must get the scores from several users and then print the highest and lowest score. I have attempted to do this by creating the loop and asking for the score and name then creating new variables for the high and lows attempted both in and out of the loop but it has not worked any help would be greatly appreciated!
/* Name: Armaan and Kenny
* Date:
* Course:
* Description:
*/
import hsa.Console;
import java.awt.*;
public class testPilo
{
static Console c;
public static void main(String[] args)
{
c = new Console();
int i = 0;
int a = 0;
int y = 0;
String x = "";
String bigBoy = "";
String lilBoy = "";
int highest = 0;
int lowest = 0;
c.println("How man players do you want?");
a = c.readInt();
while(true){
if(y >= highest){
bigBoy = x;
highest = y;
}
i++;
c.println("enter the name of gamer #"+i);
x = c.readString();
c.println("What is your score "+x+"?");
y = c.readInt();
highest = y;
lowest = y;
if(y <= lowest){
lilBoy = x;
lowest = y;
}
if(i == a) break;
}
c.println("The highest is "+lilBoy);
c.println("The lowest is "+bigBoy);
}
}
You are very close and on the right track. You should initialize highest to Integer.MIN_VALUE and lowest to Integer.MAX_VALUE. Then when you find one lower or higher, reset those values to the newer ones and continue until no more input.
Continue reading in values and names, setting appropriate values until you're finished. Then print the results.
Here is a sample.
if (val > highest) {
highest = val;
highname = currentName;
}
Also, instead of having a separate variable i for determining when to stop, you can do the following:
while (a-- > 0) {
// rest of your code here.
}

Categories