For the past few months, I switched to programming in a functional language (Racket), and recently restarted coding in Java, so I'm a bit confused regarding a few concepts.
The following (simplified version) code is an implementation of euclid's algorithm. It works just fine. My problem with it is the return statement. Is it possible in java to store the results of a method in a variable? For example,in my code, I initialized the variable result to store the gcd of two numbers. But that returns an incorrect value. However, if I remove the variable result, I get the correct value for the gcd, which brings me to my 2nd question: return statements. I don't quite understand what the return statement is doing here. The only reason I have it in the 1st place was because I was aiming to store the result of the method Recursion in a variable. But as far as I've tried it, and seems to be only messing up my code.
Primary objective: To store the result of the gcd of two numbers in a variable, so I can re-use it elsewhere.
Is there is a way to make this possible?
Any suggestions would be appreciated!
import java.util.*;
public class StoringResults
{
public static void main(String[]args)
{
int big,small,remainder,gcd; //Variables declared.
Scanner sc=new Scanner(System.in);
/* Use enters input */
//Big is the larger number.
//Small is the smaller of the two.
remainder=big%small;
int result=recursion(big,small,remainder);
System.out.println("FINAL RESULT:"+result);
}
//recursive method.
public static int recursion(int big,int small,int remainder)
{
remainder=big%small;
if(remainder==0)
{
System.out.println(small);
}
else
{
int dummyvar=remainder;
big=small;
small=dummyvar;
recursion(big,small,remainder);
}
return remainder;
}
}
As my comment already stated your logic is faulty.
And your statement if I remove the variable result,I get the correct value for the gcd is plain wrong. You get the correct result printed but not returned. And that is caused by the fact that you return the wrong value.
remove the remainder from the method signature since your first statement is assigning something to it
return the correct value: smaller instead of remained
return in the else branch
That will result in the following code:
public static int recursion(int big,int small)
{
int remainder=big%small;
if(remainder==0)
{
System.out.println(small);
}
else
{
big=small;
small=remainder;
return recursion(big,small);
}
return small;
}
Shortening results in
public static int recursion(int big, int small) {
int remainder = big % small;
if(remainder == 0) {
return small;
} else {
return recursion(small,remainder);
}
}
Adding to TDG's answer, your code should be more like this:
//recursive method.
public static int recursion(int big, int small, int remainder) {
remainder = big%small
if (remainder==0) {
System.out.println(small);
return small;
} else {
Int dummyvar = remainder;
big = small;
small = dummyvar;
return recursion(big, small, remainder);
}
}
Related
Thank you for your time!
for value upto 2147483641 code is working fine after that it is returning 0(why)..
as per my understanding program should return 0 only when overflow occurs.. (for -2147483648 and 2147483647 ) not for value falling in the range.
Also please share any link for leading zero number reversal.. I could not find any online.
public class ReverseDigit {
public int reverse(int integer) {
boolean negflag=false;
if(integer<0){
negflag=true;
integer=integer*-1;
}
int rev=0;
int rem=0;
while(integer!=0){
rem=integer%10;
int newrev= rev*10+rem;
if((newrev-rem)/10!=rev){
return 0;
}
else{
rev=newrev;
}
integer=integer/10;
}
return rev = negflag?rev*-1:rev;
}
public static void main(String[] args) {
ReverseDigit rd = new ReverseDigit();
System.out.println(rd.reverse(**2147483642**));
}
}
This is happens because the reversed number of 2147483642 is 2463847412, and this number is greater then Intrgre.MAX_VALUE which is 2147483647, so the number became less than 0.
This is happens to 2147483623 too, because his reversed number is 3263847412, and this number is greater then Intrgre.MAX_VALUE.
To fix that, I see two possible solutions:
Use long instead of int.
Rewrite the method to work with String, because you aren't really do any calculations (You can use string.charAt(int index) to get the digits one bt one).
The program is to find the HCF for m and n,where m is less than n,using a recursive function Hifact(int m,int n).The Hifact part is working but the while loop isn't even though it made sense logically.
public class test{
public static void main(int m,int n)//m<n
{
while(m%Hifact(m,n)!=0)//reduces value of m till m%Hifact(m,n)==0
{
--m;
}
System.out.println(m);
}
public static int Hifact(int m,int n)//returns largest number <= m which completely divides n
{
if(n%m==0)
{
return m;
}
else
{
return Hifact(m-1,n);
}
}
}
I believe your code would work if you instead printed Hifact(m,n) on line 8.
I tested this and the code printed 5 as desired. I also tested with some different values that still produced the correct answer.
Okay, I'm totally rewriting this question because this works and I want to know why it works.
Suppose I have a number, testNumber with a value of 567.
I want to know if the next two numbers (shouldPassTest and shouldFailTest) the same digits, but in different 10s places.
So here's the code:
int testNumber = 567;
int num1 = 5;
int num2 = 6;
int num3 = 7;
int shouldPassTest = 756;
int shouldFailTest = 777;
if(Integer.toString(shouldPassTest).matches("[5,6,7][5,6,7][5,6,7]")
{
//Do some cool stuff
}
if(Integer.toString(shouldFailTest).matches("[5,6,7][5,6,7][5,6,7]")
{
//Do some cool stuff
}
What happens when you run that, is that each digit is tested from the range of available digits (5, 6, and 7). Theoretically, shouldFailTest should actually pass the test seeing as how 7 matches one of my three criteria, albeit 3 times.
But what happens is that 777 returns false, when tested. This is precisely the result I wanted in my code, but I want to know why it happened. Does the matches method test to make sure that each number is only matched once?
Thanks!
This post was highly edited. After running my code, I found that the method does exactly what I want, but now I want to know why. Thanks.
I would use the following as regex is not a good solution to this problem:
public class Count {
private int value;
public Count() {
value=0;
}
void increment() {
value++;
}
void decrement() {
value--;
}
public int getValue() {
return value;
}
}
public static boolean isAnagram(int val1, int val2) {
Map<Character, Count> characterCountMap=new HashMap<>();
for(char c:Integer.toString(val1).toCharArray()) {
Count count=characterCountMap.get(c);
if(count==null) { count=new Count(); characterCountMap.put(c, count);}
count.increment();
}
for(char c:Integer.toString(val2).toCharArray()) {
Count count=characterCountMap.get(c);
if(count==null) { return false; }
else { count.decrement(); }
if(count.getValue()==0) {
characterCountMap.remove(c);
}
}
return characterCountMap.size()==0;
}
Please run:
System.out.println(Integer.toString(shouldFailTest).matches("[5,6,7][5,6,7][5,6,7]"));
to view the actual return value.
Theoretically, shouldFailTest should actually pass the test seeing as
how 7 matches one of my three criteria, albeit 3 times.
But what happens is that 777 returns false, when tested. This is
precisely the result I wanted in my code, but I want to know why it
happened. Does the matches method test to make sure that each number
is only matched once?
No, "777" does match the pattern you have specified "[5,6,7][5,6,7][5,6,7]"
Following condition in your code will evaluate to true.
if(Integer.toString(shouldFailTest).matches("[5,6,7][5,6,7][5,6,7]"))
It started from I want to compute 1+2+3+...+n, and
It is easy for me to figure out an recursive method to deal with repeat-plus-operation, and the code as follow:
public long toAccumulate(long num)
{
return num == 1 ? 1 : num + toAccumulate(num-1);
}
This method works just fine when use in a range of small number like 1 to 100, however, it fails to work when the parameter up to a big number like 1000000.
I wonder why?
And one leads to another, I write a repeat-times-operation method as follow:
public long toTimes(long num)
{
return num == 1 ? 1 : num * toTimes(num-1);
}
And here comes some interesting result. If I pass 100 as parameter, I will get 0. So I decrease my parameter's value, and I finally got some number when the parameter passing 60, but the result was a very weird negative number -8718968878589280256.
This got me thinking, but it didn't too much time for me to rethink something I have learnt from C, which is long long big data value type. And I assumed that negative number showed off is because the result data too big to fit in the current data type. What amazed me was I realize that there's a BigInteger class in Java, and I remembered this class can operate the big value data, so I changed the first code as follow:
public BigInteger toAccumulate(BigInteger num)
{
return num.equals(1) ? BigInteger.valueOf(1) : (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
}
But it still didn't work... and this is driving me crazy...
A question I found in the stack overflow which similar to mine
According to the people who answered the question, I guess it may be the same reason that cause the bug in my code.
But since the BigInteger class didn't work, I think this must be the solution to this kind of accumulation problem.
What will you people do when you need to accumulate some number and prevent it go out of the maximum of data type? But is this really the data type problem?
return num.equals(1)
? BigInteger.valueOf(1)
: (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
should probably be
return num.equals(BigInteger.valueOf(1))
? BigInteger.valueOf(1)
: (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
...though frankly I'd write it as a method accepting an int and returning a BigInteger.
What if you try this:
public static BigInteger toAccumulate (BigInteger num)
{
if (num.equals(BigInteger.valueOf(1)))
{
return BigInteger.valueOf(1) ;
}
else
{
// 1+2+...+(n-1)+n = (n)(n+1)/2
BigInteger addOne = num.add(BigInteger.valueOf(1));
return num.multiply(addOne).divide(BigInteger.valueOf(2));
}
}
Here's how you can do the 1*2*3*....*(n-1)*n
public static BigInteger toTimes (BigInteger num)
{
// Should check for negative input here
BigInteger product = num;
// while num is greater than 1
while (num.compareTo(BigInteger.valueOf(1)) == 1)
{
BigInteger minusOne = num.subtract(BigInteger.valueOf(1));
product = product.multiply(minusOne);
num = minusOne; // num--;
}
return product;
}
Note: This is essentially the Factorial Function
Im a beginner.
Here is a binary search code.Its showing array out of bounds error for main method.
please look into the program and kindly tell me my mistake.ill be grateful for ur service.
i have to write all this crap cause i cant post it as its asking for more details.
public class BinaryS
{
int n;
public BinaryS(int z)
{
n=z;
}
static int pos;
static boolean flag=false;
public void disp()
{
int arr[]={0,1,2,3,4};
int len=arr.length;
int first=0;
int last=len;
int mid=(int)(first+last/2);
//boolean flag=false;
while(mid>=0 && mid<=len)
{
if(n<arr[mid])
{
last=mid;
}
if(n>arr[mid])
{
first=mid;
}
if(n==arr[mid])
{
flag=true;
pos=mid+1;
}
}
if(flag==true){
System.out.println("the no."+n+"is found at"+pos);
}
else{
System.out.println("the no."+n+"is not found ");
}
}
public static void main(String args[])
{
BinaryS obj=new BinaryS(2);
obj.disp();
}
}
Currently your code does compile, and runs forever - because of this loop:
while(mid>=0 && mid<=len)
{
// Code which doesn't modify mid or len
}
Assuming it gets into that loop at all (which it does), the condition is never going to become false - so unless you return or break from within the loop (you don't) or an exception is thrown (it isn't) you're just going to keep going round the loop.
This is where you should:
Use a debugger to observe what's happening
Think about what the condition should actually be and how you want it to become false
Adjust your code to either change the condition, or change the loop body so that it modifies mid or len