Java how to return two variables? [duplicate] - java

This question already has answers here:
How to return multiple objects from a Java method?
(25 answers)
Closed 9 years ago.
after c++ i am trying to learn some java, and i have a question about the code i have been working on. I am working on a Fraction class and i got stuck in reduce section. Since the method did not let me to return both "num" and "den", I had to return "n"
This is my method
public double reduce() {
int n = num;
int d = den;
while (d != 0) {
int t = d;
d = n % d;
n = t;
}
int gcd = n;
num /= gcd; //num = num / greatestCommonDivisor
den /= gcd; //den = den / greatestCommonDivisor
return n;
}
I am trying to do "return num, den;" however it does not let me.
and this is what i get
to reduced test for 100/2 is 2.0
to reduced test for 6/2 is 2.0
when i run
System.out.println("to reduced test for " + f4.toString() + " is " + f4.reduce());
System.out.println("to reduced test for " + f6.toString() + " is " +f6.reduce());
Why do i get the 2 when when i am supposed to get 50/1 and 3/1 ? If the IDE let me return num and den at the same time, would that have fixed it?
Thanks

Java has no native way of doing this, you only can return one Object or primitive. This leaves you two options:
Return an array with length 2.
public int[] reduce()
{
...
return new int[]{num, den};
}
Return an object of a wrapper class containing the two numbers.
public Fraction reduce()
{
...
return new Fraction(num, den);
}

It looks like your reduce method is modifying the object. It's unclear what exactly you want to return. If you want the fraction to return itself, then return this;, with the method returning a Fraction in the declaration.

Related

How can I return the FIbonacci sequence using an int return type method without using recursion?

I'm trying to create a method in Java that prints the fib series up to the number passed to the method. My issue is that I'm required to use an int return type to return the series and I cannot use recursion.
My First Idea
My original idea was like shown. Which works just fine. It takes an argument of type int and returns void simply printing the numbers as they are calculated.
public void fibonacci(int num) {
int a = 0;
int b = 0;
int c = 1;
for (int i = 0; i < num; i++) {
a = b;
b = c;
c = a + b;
System.out.print(c + ", ");
}
}
What The Question Asks For
The code below shows what I was tasked to do. It asked for a method that takes an argument of type int and returns type int.
public int fibonacci(int num) {
//some code...
return x; //This is what confuses me. I know this isn't right.
}
To me this just seems impractical and maybe even impossible to use an int return type. I'm wondering if anyone knows a way this is possible.
Expected Output:
//Method call in driver class.
fibonacci(5);
//This would print to console.
1, 1, 2, 3, 5
You can use the equation [(h)^a - (j)^a] * [1/sqrt(5)].
'a' is fibonacci number wanted
'h' is [1 + sqrt(5)] / 2
'j' is [1 - sqrt(5)] / 2
public static int returnFibonacci(int a) {
double firstTerm; // calculate h
double secondTerm; //calculate j
double fib; //calculate 1/sqrt(5) with firstTerm and secondTerm
}

I want to solve Project Euler #1 more efficiently by using arithmetic progression formula, but my algorithm returns answers that are just slightly off

This is the first, inefficient method I wrote:
public int sumOfMultiplesOf3or5Under1000() {
int sum = 0;
for (int i = 0; i < 1000; i++) {
if (i % 3 == 0 || i % 5 == 0) {
sum += i;
}
}
return sum;
}
Here is my attempt at coding a more efficient solution using the arithemtic progression formula:
public int usingAP() {
return sumOfAP(3,3,333) + sumOfAP(5,5,199) - sumOfAP(15,15,66);
}
public int sumOfAP(int firstTerm, int commonDifference, int numberOfTerms){
int sum = (numberOfTerms / 2) * (2 * firstTerm + (numberOfTerms -
1) * commonDifference);
return sum;
}
When I call sumOfMultiplesOf3or5Under1000() I get the correct answer:
233168
When I call usingAP() I get an answer that's off by just 1,001:
232167
I'm not sure why you consider your first method to be inefficient for the reason that I stated in the comment above. Nevertheless, it seems you fell victim to rounding errors in your sumOfAP method. You were close, but you just need some way to store the temporary variables as double instead of int so you can retain the precision. I was able to fix it by dividing and multiplying by 2D instead of 2:
public static int sumOfAP(int firstTerm, int commonDifference, int numberOfTerms){
return (int) ((numberOfTerms / 2D) * (2D * firstTerm + (numberOfTerms - 1) * commonDifference));
}
You can run the following and verify that they're equivalent:
System.out.println(usingAP());
System.out.println(sumOfMultiplesOf3or5Under1000());
Output:
233168
233168

Java Integer to Binary Converter Code

I am trying to write a basic calculator. One of the things I want my calculator to have is a base arithmetic converter that gives an output when you input a base 10 integer.
I tried to write code for it on my own and it took nearly 3 hours just to figure out how to convert a number to a given base and it works good enough so far but I have one problem - when I try to convert an integer to base 2 (binary) my calculator does not work for numbers bigger than 1025.
I thought the problem was because there is a max value an integer can hold or something so I tried "BigInteger" but since it does not support remainder "%" operation I could not make it work.
else if(c.equals("Base")) {
g = 0;
l = 0;
System.out.println("Enter the number (Integer) you want to convert");
f = scan.nextInt();
System.out.println("Enter the arithmetic base you want for your new number");
m = scan.nextInt();
for (;f>=1;) {
h=f%m;
f=f/m;
k = (int)Math.pow(10,g);
g++;
l =l + (h*k);
}
System.out.println(l);
}
Sorry if the code is really bad and there are more efficent ways, i just wanted it to be mine instead of looking it up.
If you want to use the BigInteger class, you can use the mod method instead of "%".
BigInteger myBigInteger = new BigInteger("943838859");
System.out.println(myBigInteger.mod(BigInteger.TEN));
This will print 9.
It's not a good idea to store the "binary representation" in an int variable, since that limits you to 10 digits.
Instead, you can use a String variable to hold the result:
String l = "";
while (f > 0) {
h = f % m;
f = f / m;
l = h + l;
}
System.out.println(l);
This is the way I've tried myself (modulo/divide/add):
int decimalOrBinary = 345;
StringBuilder builder = new StringBuilder();
do {
builder.append(decimalOrBinary % 2);
decimalOrBinary = decimalOrBinary / 2;
} while (decimalOrBinary > 0);
System.out.println(builder.reverse().toString()); //prints 101011001
You can do this in a 3 lines of code using a recursive funtion,
public static String convertToBase(int n, int b) {
return n > 0 ? (convertToBase(n / b, b) + n % b) : "";
}

how to create an Exp(-x^2) function?

I am using the "think java" book and I am stuck on exercise 7.6. The goal here is to write a function that can find . It gives you a couple hints:
One way to evaluate is
to use the infinite series expansion:
In other words, we need to add up a series of terms where the ith term
is equal to
Here is the code I came up with, but it is horribly wrong (when compared to Math.exp) for anything other than a power of 1. I don't understand why, as far as I can tell the code is correct with the formula from the book. I'm not sure if this is more of a math question or something related to how big of a number double and int can hold, but I am just trying to understand why this doesn't work.
public static void main(String[] args) {
System.out.println("Find exp(-x^2)");
double x = inDouble("Enter x: ");
System.out.println("myexp(" + -x*x + ") = " + gauss(x, 20));
System.out.println("Math.exp(" + -x*x + ") = " + Math.exp(-x*x));
}
public static double gauss(double x, int n) {
x = -x*x;
System.out.println(x);
double exp = 1;
double prevnum = 1;
int prevdenom = 1;
int i = 1;
while (i < n) {
exp = exp + (prevnum*x)/(prevdenom*i);
prevnum = prevnum*x;
prevdenom = prevdenom*i;
i++;
}
return exp;
} // I can't figure out why this is so inacurate, as far as I can tell the math is accurate to what the book says the formula is
public static double inDouble(String string) {
Scanner in = new Scanner (System.in);
System.out.print(string);
return in.nextDouble();
}
I am about to add to the comment on your question. I do this because I feel I have a slightly better implementation.
Your approach
Your approach is to have the function accept two arguments, where the second argument is the number of iterations. This isn't bad, but as #JamesKPolk pointed out, you might have to do some manual searching for an int (or long) that won't overflow
My approach
My approach would use something called the machine epsilon for a data type. The machine epsilon is the smallest number of that type (in your case, double) that is representable as that number. There exists algorithm for determining what that machine epsilon is, if you are not "allowed" to access machine epsilon in the Double class.
There is math behind this:
The series representation for your function is
Since it is alternating series, the error term is the absolute value of the first term you choose not to include (I leave the proof to you).
What this means is that we can have an error-based implementation that doesn't use iterations! The best part is that you could implement it for floats, and data types that are "more" than doubles! I present thus:
public static double gauss(double x)
{
x = -x*x;
double exp = 0, error = 1, numerator = 1, denominator = 1;
double machineEpsilon = 1.0;
// calculate machineEpsilon
while ((1.0 + 0.5 * machineEpsilon) != 1.0)
machineEpsilon = 0.5 * machineEpsilon;
int n = 0; //
// while the error is large enough to be representable in terms of the current data type
while ((error >= machineEpsilon) || (-error <= -machineEpsilon))
{
exp += error;
// calculate the numerator (it is 1 if we just start, but -x times its past value otherwise)
numerator = ((n == 0) ? 1 : -numerator * x);
// calculate the denominator (denominator gets multiplied by n)
denominator *= (n++);
// calculate error
error = numerator/denominator;
}
return exp;
}
Let me know how this works!

Checksums - ISBN program

This problem has me puzzled. I tried using a loop like this: Basically I tried to get the first digit from the input and do the formula but it doesn't seem to work. It looks so simple but I can't figure it out. Could you help me? Thanks.
public static int ISBN(String ninedigitNum) {
number = 9;
while (number > 0) {
int nextDigit = ninedigitNum.substring(0,1);
...
}
Checksums (Source: Princeton University). The International Standard
Book Number (ISBN) is a 10 digit code that uniquely specifies a book.
The rightmost digit is a checksum digit which can be uniquely
determined from the other 9 digits from the condition that d1 + 2d2 +
3d3 + ... + 10d10 must be a multiple of 11 (here di denotes the ith
digit from the right). The checksum digit d1 can be any value from 0
to 10: the ISBN convention is to use the value X to denote 10.
Example: the checksum digit corresponding to 020131452 is 5 since is
the only value of d1 between 0 and and 10 for which d1 + 2*2 + 3*5 +
4*4 + 5*1 + 6*3 + 7*1 + 8*0 + 9*2 + 10*0 is a multiple of 11. Create a
Java method ISBN() that takes a 9-digit integer as input, computes the
checksum, and returns the 10-digit ISBN number. Create 3 JUnit test
cases to test your method.
I got it, thanks a lot everyone!
What about it isn't working? Either way, I believe what you're missing is that you're continually getting the same substring, which will be the first number of the string: int nextDigit = ninedigitNum.substring(0,1);. In addition, you're going to want to use an int, not a String; you can technically convert from String to int if desired, but the problem itself calls for an int.
There are two ways to do this that jump to mind. I would do this by realizing that mod in powers of 10 will give you the respective digit of an integer, but the easier way is to convert to a char array and then access directly. Note that there's no error checking here; you'll have to add that yourself. In addition, there are a LOT of 'magic numbers' here: good code typically has very, very few. I would recommend learning more data structures before attempting problems like these; to be honest there's very few things you can do without at least arrays and linked lists.
char[] ISBN = ninedigitNum.toCharArray();
//Process each number
int total = 0;
for(int i=0; i<9; i++){
int current_int = Integer.parseInt(ISBN[i]);
total += current_int * (10 - i)
}
//Find value of d1
for(int i=0; i<9; i++){
if(((total + i) % 11) == 0){
total += i*100000000;
break;
}
}
return total;
In general: Use print outs with System.out.println(x); or use your compiler's debugger to see what's going on during processing.
So,
This is the piece of code that I wrote. I still think it could be made more efficient.
public class Problem3 {
public static String ISBN(String x)
{
char[]temp = x.toCharArray();
int counter = 2;
int sum = 0;
int j=0;
for(int i=8;i>=0;i--)
{
sum+= counter*Integer.parseInt(""+temp[i]);
counter+=1;
}
for(j=0;j<10;j++)
{
if((sum+j)%11==0)
{
break;
}
}
return x+""+j;
}
public static void main(String args[])
{
String a = "020131452";
System.out.println(ISBN(a));
}
}
Hope this helps.
This works:
public static int ISBN(String nineDigitNum){
int sum = 0;
for(int i = 0; i<nineDigitNum.length(); i++){
sum += Integer.parseInt(""+nineDigitNum.charAt(i))*(10-i);
}
return (sum%11);
}
Also I believe if the checksum is == to 10, it should return an X, so you could either change the return type and add an if statement somewhere, or just put the if statement outside wherever you are using this method.
Here is a short one without loops that uses only substring(), charAt() and length():
public static String ISBN(String nineDigits) {
int chkD = 11 - checkDigit(nineDigits, 0);
return nineDigits + ((chkD == 10) ? "X" : chkD);
}
public static int checkDigit(String nDsub, int chkD) {
if (nDsub.length() == 0)
return 0;
chkD = ((nDsub.charAt(0) - '0') * (nDsub.length() + 1));
return (chkD + checkDigit(nDsub.substring(1), chkD)) % 11;
}
Output:
> ISBN("123456789")
"123456789X"
> ISBN("123456780")
"1234567806"

Categories

Resources