I am new to programming and wrote this code for recursive binary search, but the output is wrong.
I tried debugging it many times but could not know where I am going wrong.
public class Number {
public static void main (String[] args){
int []a = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
int key = 7;
int mid,low,high;
low=0;
high=a.length-1;
int pos=binarySearch(a,key,low,high);
System.out.println(key +" is found at "+pos+" position");
}
public static int binarySearch(int[]a,int key,int low, int high) {
int mid=(low+high)/2;
if(key<a[mid]){
high=mid-1;
binarySearch(a,key,low,high);
}
else if(key >a[mid]){
low=mid+1;
binarySearch(a,key,low,high);
}
else if(low>high){
return -1;
}
return mid;
}
}
During recursive calls execution of caller is interrupted and his execution frame is pushed onto stack. When callee finishes execution callers frame is retrieved from the stack and his execution proceeds. You assigned 9 to mid and you returned mid without reassigning it. If you try different size arrays you will see that always initial mid is returned and all recursive calls are made for no reason. To debug place one System.out.println("returning "+mid); in front of return statement.
//ignores found value
binarySearch(a,key,low,high);
should be
//returns value
return binarySearch(a,key,low,high);
in both "if" and "else if" clause
You should first check if mid equals key. If it does, escape.
Related
I want to return a value from a for-if statement in java but unfortunately i am not able to do so.
I did try to return a value from inside a if statement from a for loop, but got an error
You have missing return statement because every branch of the code should return something, here in case the array is empty, then you don't do anything of the loop you'll have no return
Then you have put the else in the loop, so if the first number is not the one loop you for you return -1 meaning not found.
You need to wait the whole loop before being able to tell that you didn't find it
And that behaviour fix, solves the syntax issue too
public int search(int[] nums, int target){
for(int i=0; i<nums.length; i++){
if(nums[i] == target)
return i;
}
return -1;
}
The problem with your code (using you image here):
Even though you have the return inside the IF statement and the ELSE statement, they will only be reached only IF the code gets inside the FOR statement.
What would happen if you call your method with an empty nums array? if would skip the for statement and there is NOTHING to return for your method in this case, do you get it?
That's why you need a return outside the for/loop as well, meaning that: What your method wants to return if reaches this point?.
If it is a search, for example, you could return -1 outside the FOR/Loop and remove the ELSE statement from inside.
Don't wanna change to much your code, so you clearly see the difference, since you are clearly starting:
public int search(int[] nums, int target) {
int i;
int j;
int n = nums.length;
for (i=0;i<n;i++){
if (nums[i]==target) {
return (i);
}
}
return (-1);
}
I am learning Java programming and made a program which uses Binary Search to find a symbol in an array of char. However, I have a problem when I try to search for the symbol which is not in an array, my program becomes an endless cycle. I have no idea how to make an error sign if there is no such symbol in an array. Here is the code of my program
import java.lang.reflect.Array;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
char[]arr = {'a','d','f','l','o','z'};
find(arr,'m');
}
public static void find(char[]arr,char ch){
int last = arr.length-1;
int mid=last;
while (arr[mid] != ch){
if (arr[mid]<ch){
mid = (last+mid)/2;
}
else{
last=mid;
mid=last/2;
}
}
System.out.print(mid);
}
}
Thank you in advance.
You have no case to break out of the while loop and the changed values assigned to the variables during the 2 if cases are incorrect. Plus, you should also check for when the element is found in the if-else ladder and use a variable (found) to indicate whether the element is found. Moreover, it'll be better if you use 3 variables for the lower bound (first), mid and upper bound (last). The code below is a revision of the find() method.
public static void find(char[]arr,char ch){
int first=0,mid=0,last=arr.length-1,found=0;
while (first<=last){
mid=(last+first)/2;
if(arr[mid]==ch){
System.out.print(ch+" found at index "+mid);
found=1;
break;
}
else if(arr[mid]<ch){
first=mid+1;
}
else if(arr[mid]>ch){
last=mid-1;
}
}
if(found==0)
System.out.print(ch+" was not found ");
}
This works fine and maybe you should use this method.
You have to make some changes in your find() method.First check that the value of mid should never exceed the value of last,so you have to change your while loop condition accordingly. Secondly you have to give a terminating condition if(arr[mid]==ch) to come out of the loop.
This can also be done by using two variables lo & hi ,easy to understand & implement.See the implementation here Binary Search.
Below is the solution using only only last & mid variables,as per your code requirement above:
public static void find(char[]arr,char ch){
int last = arr.length-1;
int mid=last/2;
while (mid<=last){
if(arr[mid] == ch) //if found, Print and exit the loop
{
System.out.println("found at:"+mid);
return;
}
if (arr[mid]<ch){
mid=((last+mid)/2)+1;
}
else{
last=mid-1;
mid=last/2;
}
}
System.out.println("Not found!!");
}
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);
}
}
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
I dont understand why this is forward recursion:
int count(int x) {
if(x<=0) return 0;
return 1 + count(x - 1);
}
It's a question on a practice exam, and the answer is that its forward recursion. Why is this the case? How could I distinguish between the two?
You're doing an addition after calling yourself. Tail recursion means absolutely nothing can be after
If you understand the implementation, it's clear why.
Say we call count for the first time from main, which is at program counter 0xAAA. It then does most of its method. We'll say the recursive call to count is at 0xBBB for this stack frame. If you're using tail recursion, when calling itself, it can set the return address as 0xAAA (just go straight to the code that called me). If it's doing anything after, it must set the return address as 0xBBC (the address of the addition). Because it doesn't need stack frames to store return addresses, it's also much easier to transform the recursion to iteration. When count calls itself, it can just jump to the beginning of the method.
The solution (to the trivial example) is to build up the result in another parameter:
int count(int x, int res) {
if(x<=0) return res;
return count(x - 1, res + 1);
}
Note we do nothing after.
Did you look at this SO question, tail vs forward recursion?
Matthew has the answer,and the long form would be that:
int count(int x) {
if(x<=0) return 0;
return 1 + count(x - 1);
}
can be written as (and is expanded as something like):
int count(int x) {
if(x<=0) return 0;
int tmp_result = count(x - 1);
return 1 + tmp_result; // e.g. recursion is not last
}