So here is my problem. I need help trying to figure out what I'm doing wrong and go from there. I need to create a program that runs these instructions.
Create java class named Fraction. This class is used to represent a ratio of two integers. Include mutator methods that allow the user to set the numerator and the denominator. Also include a method to display the fraction on the screen as a ration (e.g. 5/9). This method does not need to reduce the fraction to lowest terms.
The fraction class should contain the following:
• Private instance variables to store the numerator, denominator, and the ratio_value.
• Constructor(s) that set all of the instance variables.
• Public methods to get and set the instance variables.
• A public method named reduce( ) that returns lowest terms of a fraction.
• A public method named toString( ) that returns a String containing the fraction as a ratio.
• A private method name gcd() that return the greatest common divisor of two integers.
Create a test program that allows the user to create array of 7 fractions. Then the program will sort the fraction in ascending order. The highest and the lowest fractions are thrown away and the remaining fractions are added together. The program should display all the fractions and their sum. The sum should be reduced to lowest terms and displayed on the screen. For example, if the sum is 20/60, the program should display 1/3.
Write a sort method in the test program to sort the array of fractions and calculate the sum.
Assume you have the following 7 fractions: 6/7, 2/4, 3/4, 3/18, 1/8, 10/20, 2/6, then an example of the output after throwing away the lowest and the largest fractions, will be:
3 / 18 + 2 / 6 + 2 / 4 + 10 / 20 + 3 / 4 = 9 / 4
I completely lost on how to solve this and stuck where I am at. Below is a copy of my class and .main file. I have some different things that I have tried commented out with '//' so sorry for the long codes in advance. I've tried over and over to figure this and have been stuck for days. It keeps giving me this weird error called null.
How can I get this to work? Thanks.
import java.io.*;
import java.util.*;
public class Arrays_hw5 {
private static final Scanner keyb = null;
public static void main(String[] args) {
Fraction [] fr = new Fraction[7];
String reduce = "";
int numerator = 0, denominator = 0;
Scanner keyb = null;
FileInputStream fis = null;
//Scanner keyb = new Scanner(System.in);
try {
fis = new FileInputStream(new File("Fraction"));
keyb = new Scanner(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();}
for (int i = 0; i < fr.length; i++) {
//System.out.println("Enter numerator then denominator, hit enter after each entry: ");
// fr[i] = new Fraction(i, i);
// fr[i].getNumerator(keyb.nextInt());
// fr[i].denominator(keyb.nextInt());
System.out.print(fr[i] + " "); }}
public static void selectionSort(int[]arr)
{
int smallest = 0;
for (int outer = 0; outer < arr.length - 1; outer++)
{
smallest = outer;
for(int inner = outer + 1; inner < arr.length; inner++)
{
if (arr[inner] < arr[smallest])
smallest = inner;
}
int v = arr[outer];
arr[outer] = arr[smallest];
arr[smallest] = v; }
}
}
Here is the Fraction Class.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Fraction {
public int numerator = 1;
public int denominator = 1;
public int gcd;
public Fraction() {
super();
}
public Fraction(int n, int d) {
numerator = n;
denominator = d;
}
public int getNumerator() {
return numerator;
}
public void setNumerator(int numerator) {
this.numerator = numerator;
}
public int getDenominator() {
return denominator;
}
public void setDenominator(int denominator) {
this.denominator = denominator;
}
private static int gcd(int numerator, int denominator) {
return denominator == 0 ? numerator : gcd(denominator, numerator % denominator);
}
public double decimal(double numerator, double denominator) {
return numerator / denominator;
}
public static String reduce(int numerator, int denominator) {
int gcd = gcd(numerator, denominator);
return (numerator / gcd) + "/" + (denominator / gcd);
}
#Override
public String toString() {
return numerator + "/" + denominator;
}}
Prepare yourself for a long answer. First it is always best to plan out a project before doing any code so here are the steps we will take: 1) Read input from user and store this input into an array of Fractions. 2) Sort this Fraction array then remove (ignore) highest and lowest values in array. 3) Sum all values of array excluding highest and lowest values, reduce this sum, and print this sum to the screen.
Step 1) Read User Input
You are on the right track but you do not read the user input properly. First, you for some reason open a file. This is unnecessary as you only need to read from the command line. Second, you do not read nor store the input properly. I would suggest repeatedly prompting the user to input a numerator then a denominator. And for every time you read one numerator and one denominator, store these values as a Fraction before you re-prompt the user for input. See the following code block to understand what I mean:
Fraction[7] fractions = new Fraction[7]; // array that will hold our fractions
Scanner inputScanner = new Scanner(System.in); // scanner that takes input from the command line
...
public void readInput()
{
int tempNumer; // variable to store numerator on each iteration
int tempDenom; // variable to store denominator on each iteration
for (int i = 0; i < fractions.length; i++)
{
System.out.println("Enter a numerator:");
tempNumer = inputScanner.nexInt(); // store the user-inputted numerator
System.out.println("Enter a denominator");
tempDenom = inputScanner.nextInt(); // store the user-inputted denominator
fractions[i] = new Fraction(tempNumer, tempDenom); // store a Fraction from our temp variables into our fractions array
}
return;
}
Upon completion of this method, the fractions array will be full of Fraction objects in the order that the user inputted.
Step 2) Sort the fractions array
So, how do we know if a fraction, in normal math, is larger than another fractions? Well, we convert both fractions to have the gcd as each individual fraction's denominator, then we compare the numerators (btw, your gcd method is so wrong. The gcd is between two fraction's denominators, NOT the numerator and denominator of one fraction). The larger numerator at this point is the larger fractions. So, it would be easiest to have a method called fracCompare that takes in two fractions, converts both of them, then return which fraction is larger. We can do this as follows:
public int fracCompare(Fraction fracOne, Fraction fracTwo)
{
// First, find the gcd of the fractions
int gcd = gcd(fracOne.getDenominator, fracTwo.getDenominator);
// Now, we need to convert the numerator accordingly
// We will do this by finding the factor by which the denominator is
// increased and multiply the numerator by this factor
int factorOne = gcd / fracOne.getDenominator();
int tempFracOneNum = fracOne.getNumerator() * factorOne;
int factorTwo = gcd / fracTwo.getDenominator();
int tempFracTwoNum = fracTwo.getNumerator() * factorTwo;
// Now we compare these numerators
// We will return 1 if fracOne is greater than fracTwo
// We will return 2 if fracTwo is greater than fracOne
// We will return 0 if they are the same
if (tempFracOneNum > tempFracTwoNum)
return 1;
else if (tempFracTwoNum > tempFracOneNum)
return 2;
else
return 0;
}
public int gcd(int firstNum, int secondNum)
{
int a = firstNum.getDenominator();
int b = secondNum.getDenominator();
while(a != 0 && b != 0) // until either one of them is 0
{
int c = b;
b = a % b;
a = c;
}
return a+b; // either one is 0, so return the non-zero value
}
A note: I blatantly stole this gcd method from The user, Rushil's answer on another post. Now that we have a compare method, we can sort the array. I will leave the sorting to you because I'm getting sick of formatting code but here is some bubble sort pseudocode to get you started:
i = 0
loop until i = fractions.length - 1
j = i
loop until j = fractions.length - 1
if fraction at j > fraction at j+1
swap fraction at j and fraction at j+1
Step 3) Sum all Fractions in fractions array
Finally at the last step. In order to add fractions we again need to use the gcd. We use this gdc to see what to increase the numerator of both adding fractions by. We will then take this sum and add it to all the other values in the array. Finally, we will reduce the large sum.
int tempGcd;
int tempFactorOne;
int tempFactorTwo;
Fraction sum = fractions[1];
for (int i = 2; i < fractions.length - 2; i++) // we loop from 2 to fractions.length-2 because
// we ignore the least and greatest values in the array
// and we assigned the initial sum to the first fraction
{
tempGcd = gcd(sum.getDenominator(), fractions[i].getDenominator());
tempFactorOne = tempGcd / sum.getDenominator();
tempFactorTwo = tempGcd / fractions[i].getDenominator();
sum.setNumerator(tempFactorOne * sum.getNumerator() + tempFactorTwo * fractions[i].getNumerator()); // add the numerators and store as the sum
sum.setDenominator(gcd); // obviously the denominator is the gcd
}
Hopefully this all should work. I'm sick of typing so I'll leave the reducing of the fraction to you. It is pretty simple--you just need to find the greatest common divisor of the numerator and denominator and then divide both by that divisor. Sorry if my exact code doesn't compile, I'm too lazy to do it myself and you shouldn't be plagiarizing for a school project anyway.
Related
Here is my code. I tried to Convert the binary to a Char array, then multiply each char in the array by 2 to the power of its corresponding number in the array, then sum up all the values of the char array into a double. New to programming so a bit confused. My input Binary is txfBinaryInput, and my output label is lblDisplay.
private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)
{
if (txfBinaryInput.getText().equals(""))
{
lblDisplay.setText("ERROR: NO INPUT");
} else
{
int n = 0;
int[] binaryValueStorage = new int[100];
double[] decimalValueStorage = new double[100];
String binaryInput = txfBinaryInput.getText();
int binaryNumber = binaryInput.length();
char[] binaryDigits = binaryInput.toCharArray();
for (int i = 0; i >= binaryNumber; i++)
{
binaryValueStorage[n] = binaryDigits[n];
decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, n));
n++;
}
double sum = 0;
for (double a : decimalValueStorage)
{
sum += a;
}
lblDisplay.setText("The Deciaml Value Is " + sum);
}
}
Beware: in your for loop condition, you have i >= binaryNumber instead of i < binaryNumber, therefore your program will never enter the loop!
And on a side note, why are you using two variables, i and n, for the same purpose (incrementing and accessing the array)?
Edit: another issue:
In binary numbers, lower order bits are to the right, but in arrays, indices are from left to right!!
So you want your rightmost digit to be multiplied by 2^0, the next one right to its left by 2^1, and so on.
But in your code, what is happening is the opposite: it is the leftmost digit (your digit at index 0) that is being multiplied by 2^0!
To fix, you can either:
1) reverse your binaryDigits array before starting to convert, and keep the rest of your code untouched
2) replace decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, n)); by decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, binaryNumber - n));
Hope this helps!
Well, this is a lot to throw at you, but this is how I'd attack this problem:
public class BinaryToDecimalTest {
private static long binaryToDecimal(String binaryInput)
{
long sum = 0;
for (int i = 0 ; i < binaryInput.length() ; i++) {
sum *= 2;
if (binaryInput.charAt(i) == '1')
sum += 1;
}
return sum;
}
private static void test(String binaryInput) {
long n = binaryToDecimal(binaryInput);
System.out.println(String.format("The Deciaml Value of %s Is %d", binaryInput, n));
}
public static void main(String...args) {
test("0100");
test("1011");
test("1011");
test("10000000");
test("10000000000000000");
}
}
Result:
The Deciaml Value of 0100 Is 4
The Deciaml Value of 1011 Is 11
The Deciaml Value of 1010 Is 10
The Deciaml Value of 10000000 Is 128
The Deciaml Value of 10000000000000000 Is 65536
I don't want to just hit you with code, but I didn't know where to start given all of the issues with your code. I wanted you to see how directly you can often attack a problem. I'd be happy to keep working with you, and explain what's going on here.
The one dirty trick I'm using is multiplying the entire accumulated sum by two each time around. This lets you work naturally from the front of the array, rather than having to work your way backwards. The first digit gets multiplied by 2 (length - 1) times, the second (length - 2) times, etc., down to the last number, which doesn't get multiplied at all.
I have a solution for the Kattis Problem https://open.kattis.com/problems/almostperfect. The solution is accepted, but the runtime is too long (>1.00s).
I tried everything to solve this issue. What can I do to further improve the performance of my code?
import java.io.FileInputStream;
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class almostperfect {
public static int perfect(int number){
// 2 = perfect
// 1 = almost perfect
// 0 = not perfect
int sum = 0;
int b = 0;
for(int i=1;i<number;i++)
{
if(number%i==0)
{
sum = sum + i;
}
}
if(sum == number){
b = 2;
} else if(Math.abs(sum-number)<=2){
b = 1;
}
return b;
}
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
ArrayList<Integer> input = new ArrayList<Integer>();
int a;
int status;
while(scan.hasNextLong()){
input.add((int) scan.nextLong());
}
for(int i=0; i<input.size(); i++){
a = input.get(i);
status = perfect(a);
if(status==2){
System.out.println(a+" perfect");
} else if (status==1){
System.out.println(a+" almost perfect");
} else {
System.out.println(a+" not perfect");
}
}
}}
When you calculate the divisors of number, you don't have to loop from 1 to number, but to the square root of number. Take 100 for example - if 2 is a dividor of 100, so is 100/2.
int sum = 1; //1 is always a divisor
int b = 0;
int sqr = (int)Math.sqrt(number);
for(int i=2;i< sqr;i++)
{
if(number%i==0)
{
sum = sum + i;
sum = sum + number/i;
}
}
//Check what happens for sqr - if it's a divisor, add it only once
if (sqr * sqr == number)
sum += sqr;
Your code is fine, what is not fine is the method of finding the factors for the number it implements. You need to be smarter than brute force checking every possible number smaller than number if it is a factor.
First, obviously 1 is always a factor, since any number divides by 1 without a remainder. Also, by definition the number itself is not a factor. This restricts factors to be found to the range (2 ... n-1).
Second, if you find a divisor, then the dividend is also a divisor:
dividend = number / divisor -> implies: dividend is also a divisor
This means divisors are always found in pairs (dividend is also a divisor, making the pair). The one exception that must be accounted for is that dividend may be the same as dividend (e.g. number = 9, divisor = 3 -> dividend = 3). This can be exploited, leading to:
Third, when starting testing from the smallest possible divisor (2), the first dividend you find is the largest divisor possible, with dividends decreasing steadily while you increase the tested divisor. This means there is no need to explicitly check for divisors that are found as dividend. That means the upper testing limit would be where divisor and dividend become equal, in other words the root of number.
As stated for the problem in the link, numbers may be in range 1 ... 1E9. Your brute force method needs 1 billion tests for 1E9, while the smart version exploiting above properties, only needs 31621. Thats about factor 30000 faster!
So i was calculating e(third row in picture) with numerical methods.
I was increasing the number of elements i used every iteration. And when i executed the program, floating point variable behaved in a way i didn't understand. Here is the program and the result.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int factorial = 1;
int counter = 0;
int iterationNumber;
double total = 0;
int tempCounter;
System.out.print("Enter iteration number: ");
iterationNumber = input.nextInt();
while (counter <= iterationNumber) {
tempCounter = counter;
while ((tempCounter - 1) > 0) {
factorial *= tempCounter;
tempCounter--;
}
total += ((double)1 / factorial);
System.out.println(total);
factorial = 1;
counter ++;
}
}
}
So my question is why does the value of e starts to decrease after a while instead of increasing? I want to learn how floating point variable behaves during this program and the logic behind it.
Another question is why does it start to say infinity?
n! quickly exceeds Integer.MAX_VALUE and overflows to a negative number. You are then adding a negative number to your total --- thus the decrease.
You can use BigDecimal for your calcualtions. It is slower, but will do the job.
Write a method that computes the sum of the digits in an integer. Use
the following method header: public static int sumDigits(long n)
Programming problem 5.2. Page 212.
Please forgive my newness to programming. I'm having a hard time understanding and answering this question. Here's what I have so far. Please assist and if you dont mind, explain what I'm doing wrong.
import java.util.Scanner;
public class PP52v2 {
public static void main(String [] args) {
int sum = sumDigits(n);
System.out.println("The sum is: " + sum);
}//main
public static int sumDigits(long n) {
Scanner input = new Scanner(System.in);
System.out.println("Enter your digits");
n = input.nextLong();
int num = (int)(n);
int sum;
while(num > 0) {
sum += num % 10; //must mod - gives individual numbers
num = num / 10; //must divide - gives new num
}//loop
return sum;
}//sumDigits
}//class
Basically, you should not be handling the user input inside of the method. You should be passing the user input into your method. Other than that, everything looks good. I've made that slight change below:
import java.util.Scanner;
public class PP52v2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter your digits");
long n = input.nextLong();
int sum = sumDigits(n);
System.out.println("The sum is: " + sum);
}// main
public static int sumDigits(long n) {
int num = (int) (n);
int sum = 0;
while (num > 0) {
sum += num % 10; // must mod - gives individual numbers
num = num / 10; // must divide - gives new num
}// loop
return sum;
}// sumDigits
}// class
Do the prompt
System.out.println("Enter your digits");
n = input.nextLong();
in your main(String[] args) method because n is not currently declared in the scope of the main method.
public static int sumDigits(int num) {
int sum = 0;
while(num > 0) {
sum += num % 10; //must mod - gives individual numbers
num = num / 10; //must divide - gives new number
} //End loop
return sum;
}
For one, you should not read in the number within this method, as it accepts the number as a parameter. The method should be invoked after calling long inputNum = input.nextLong(); by using int digitSum = sumDigits((int)inputNum).
When writing a method, you have input, output, and side effects. The goal is to choose the right combination of the three so that the method, and program as a whole, words as expected.
It seems like your method is supposed to take a number as input and return each digit added together into one final sum.
Write A Test
Usually when you program, you come up with some code that uses your imaginary function. This is called a test. For a test, this could work:
System.out.println("123 should be 6: " + sumDigits(123));
Choose A Signature
You've already managed to right the correct signature. Nice!
Implement Method
Here's where you're a bit confused. Read through what every line of code does, and see if it is accomplishing your goal.
// set up a scanner for reading from the command line
// and print a message that you expect digits
Scanner input = new Scanner(System.in);
System.out.println("Enter your digits");
// read the next long number from the input stream
n = input.nextLong();
Why is this part of your method? You already have the number passed in as the argument n.
// cast the number to an integer
int num = (int)(n);
Again, not sure what this is accomplishing, besides the possibility of a bug for large numbers.
// initialize the sum variable to 0.
int sum;
Would be clearer to explicitly set the sum to 0. int sum = 0;
// add the last digit and truncate the number in a loop
while(num > 0) {
sum += num % 10; //must mod - gives individual numbers
num = num / 10; //must divide - gives new num
}
// actually return the calculated sum
return sum;
This seems like the only part of the method you need. Hopefully this helps!
Since the input number can be either positive or negative, you need to convert it to its absolute value to get the sum of digits. Then for each iteration, you add the remainder to the total sum until the quotient is 0.
public static int sumDigits(long n) {
int sum = 0;
long quotient = Math.abs(n);
while(quotient > 0) {
sum += quotient % 10;
quotient = (long) quotient / 10;
}
return sum;
}
Your code works fine for me.
i just changed int sum = sumDigits(n) to int sum = sumDigits(0) since n wasn't declared.
To have it done correctly, you just would have to put your scanner into the main method and pass the result of it (the long value) to your method sumDigits(long n).
The project I am currently working on calls for the program to take in two fractions, add them together and simplify the answer. I have finished add the fractions together just fine but I cannot figure out how to simplify the fractions.
P.S. everything I have seen so far so far on the topping is really confusing and it would help if you could make the answer simple
THANKS!
import java.io.*;
import java.util.*;
import static java.lang.Math.*;
public class Fractions {
public static void main(String[] args) {
Scanner Scan = new Scanner(System.in);
System.out.println("Numerator A");
int NuA = Scan.nextInt();
System.out.println("Denominator A");
int DeA = Scan.nextInt();
System.out.println("Numerator B");
int NuB = Scan.nextInt();
System.out.println("Denominator B");
int DeB = Scan.nextInt();
double NumA = NuA * DeB;
double NumB = NuB * DeA;
double Denominator= DeA * DeB;
double Numerator=NumA + NumB;
}
}
First, remember how one reduces a fraction to lowest terms. Given integers a and b,
a/b == (a/m)/(b/m) where m is the greatest common divisor of a and b.
The greatest common divisor, written gcd(a, b) or just (a, b) in mathematics, is most easily obtainable by using Euclid's algorithm:
(111, 45) == (21, 45) since 111 = 2 * 45 + 21.
== (45, 21)
== (3, 21) since 45 = 2 * 21 + 3
== (21, 3)
== (0, 3) since 21 = 7 * 3 + 0.
== 3 stop when one number is zero.
Now, neither Integer nor Number nor Math have a gcd method, and you should write one yourself only if you're doing it to learn the algorithm. However, BigInteger has the method. So, create a Fraction class. We'll make it immutable, so we can extend Number, and so we should reduce it to lowest terms as we construct it.
public class Fraction extends Number {
private final BigInteger numerator;
private final BigInteger denominator;
public Fraction(final BigInteger numerator, final BigInteger denominator) {
BigInteger gcd = numerator.gcd(denominator);
// make sure negative signs end up in the numerator only.
// prefer 6/(-9) to reduce to -2/3, not 2/(-3).
if (denominator.signum() == -1) {
gcd = gcd.negate();
}
this.numerator = numerator.divide(gcd);
this.denominator = denominator.divide(gcd);
}
}
Now, add the rest of your math routines. Notice that I did nothing about nulls, division by zero, infinities, or NaNs.