Binary search doesn't return anything - java

I'm trying to run a binary search where the user can input a value and my binary search method will return a part number and price but it doesn't return anything when any value is entered. The search is used on parallel arrays. I call the method below in main.
public int binSearch(int target)
{
int first = 0;
int last = numCount -1;
boolean found = false;
while(first <= last && !found)
{
mid = (first + last)/2;
if(partNum[mid]==target)
{
found = true;
}
else if(partNum[mid]<target)
{
first = mid +1;
}
else if(partNum[mid]>target)
{
last = mid -1;
}
else if(!found)
{
mid = -1;
}
return mid;
}
Here is the code that calls the method in the main class.
index = inputDevice.nextInt();
while(inventoryArray.binSearch(index) >= 0);
{
System.out.printf("Binary search found part #%d. The price is $%d\n", index, inventoryArray.binSearch(index));

Your array is supposed to be sorted.
You need to set the return outside the loop
and when the last condition is reached ( which is supposed to mean that the target is not in the sorted array) you should break after setting mid = -1 , and no need to check if its found
while(first <= last && !found)
{
mid = (first + last)/2;
if(partNum[mid]==target)
{
found = true;
}
else if(partNum[mid]<target)
{
first = mid +1;
}
else if(partNum[mid]>target)
{
last = mid -1;
}
else
{
mid = -1;
break;
}
}
return mid;

Related

Binary search algorithm isn't returning variable

I'm very new to binary search and I attempted a code that would read values from a document and then the user can input a number to search for from the document, and through binary search, the number would be found. I'm having trouble now because the "low" variable that I initialize in the binary search section of my code is not being returned to my main code and there's an error that says "low can not be resolved to a variable".
Here is the code for my binary search:
static public int search (int[]numbers,int target, int count)
{
int high = numbers.length;
int low = -1;
int middle = (high+low)/2;
while(high-low>1)
{
count++;
middle = (high+low)/2;
if(numbers[middle]>target)
{
high = middle;
}
else if(numbers[middle]<target)
{
low = middle;
}
else
{
break;
}
System.out.println(numbers[middle]);
System.out.println(middle);
}
if(low == -1 || numbers[low]!=target)
{
low=-1;
return low;
}
else
{
return low;
}
}
And here is the code from my main code. The part with the if statements is where the error is showing up:
public static void main(String[] args) throws IOException {
DataInputStream input = new DataInputStream(System.in);
int [] numbers = new int [50000];
int target;
int count=0;
try
{
BufferedReader br = new BufferedReader(new FileReader("randNums.txt"));
for(int i=0;i<50000;i++)
{
numbers[i]=Integer.parseInt(br.readLine());
}
br.close();
Arrays.sort(numbers);
System.out.print("Choose a number between 1-100000000 to search for: ");
target = Integer.parseInt(input.readLine());
search(numbers, target,count);
if(low==-1)
{
System.out.println("The number was not on the list.");
}
else
{
System.out.println("The number is at position " + low);
System.out.println("It took " + count + " comparisons to find the number.");
}
}
You have to initialize low in main:
int low=search(numbers, target,count);
I have Already resolved this algorithm.
Try my code :
public static int guessNumber(int number) {
int first = 0;
int last = 1_000_000;
if (verify(first) == 0) {
count++;
return first;
}
if (verify(last) == 0) {
count++;
return last;
}
while (last > first && count <= 50) {
count += 1;
// get the middle of the range
int middle = (first + last) / 2;
if (verify(middle) == 0) {
return middle;
}
if (verify(middle) == 1) {
first = middle + 1;
if (verify(first) == 0) {
return first;
}
}else {
last = middle - 1;
if (verify(last) == 0)
return last;
}
}
return 0;
}
//Function verify(integer) => integer
public static int verify(int guess){
if (numberTobeGuessed > guess ) {
return 1;
}else if (numberTobeGuessed < guess) {
return -1;
}
return 0;
}
I recently found a solution for lazy peoples like me use below code
int position = Arrays.binarySearch(numbers , target);
here no need to sort, and array variable number integer variable target.

java.lang.ArrayIndexOutOfBoundsException error when doing a binary search?

i am getting a little problem and i really do not know why. i am trying to program to search for a number input by the user using a binary searching method. it works well when the number in the middle of the array is searched for but when i attempt to search any other number am getting an error. here is my code.
import java.util.Scanner;
public class Main {
public static void main(String args[])
{
//declaring array
int array[] = {12,23,34,45,56,67,78,89};
//declaring variables
int search = 0;
Scanner input = new Scanner(System.in);
System.out.print("\n Enter: ");
search = input.nextInt();
binarySearch(array, search);
}//end of main
static public void binarySearch(int[] array, int search)
{
int begin = 0;
int end = array.length-1;
int mid = 0;
boolean found = false;
while(!found)
{
mid = (begin + end)/2;
if(array[mid] == search)
{
found = true;
search = array[mid];
}
else if(array[mid] < search)
{
begin = array[mid+1];
}
else if(array[mid] > search)
{
end = array[mid-1];
}
}//end of while loop
//if(!found)
//return ("BOOHOO your search was not found");
System.out.print("Yippee i found "+ search + " at index " + mid);
}
}//end of class
When you don't find a search, you need to reset your begin and end pointers to the indexes and not on the values on those indexes i.e.
while(!found)
{
mid = (begin + end)/2;
if(array[mid] == search)
{
found = true;
}
else if(array[mid] < search)
{
begin = mid+1;
}
else if(array[mid] > search)
{
end = mid-1;
}
}//end of while loop

JAVA: comparing a String with a SubString

So here's what I'm trying to accomplish. I'm trying to make a code that does the following from 2 given Strings: a target and a source.
// Determines whether the string TARGET occurs as a substring of string SOURCE where "gaps" are allowed between characters of target.`
// That is, the characters in TARGET occur in SOURCE in their given order but do not have to be adjacent.`
// (Pictured another way, this method returns true if TARGET could be obtained from SOURCE by removing some of the letters of SOURCE.)`
// This method is case sensitive. For example,`
// containsWithGaps("hamburgers", "mug") returns true`
// containsWithGaps("hamburgers", "burrs") returns true`
// containsWithGaps("hamburgers", "hamburgers") returns true`
// containsWithGaps("hamburgers", "gum") returns false`
// containsWithGaps("hamburgers", "hamm") returns false`
// containsWithGaps("hamburgers", "") returns true`
// Parameters:`
// SOURCE - the given string in which to find the target characters`
// TARGET - the characters to be found`
// Returns:`
// true if the characters in TARGET can be found as a subsequence in SOURCE, false otherwise`
And here's the code I've written. It seems to be overly complicated for what I believe shouldn't be a difficult task, but no matter what, I still keep getting errors and it won't work if given a SOURCE string hamburgers with a TARGET string burr:
public static boolean substringWithGaps(String source, String target) {
boolean substring = false;
int[] target_index;
target_index = new int [target.length()];
if (target.length() > source.length()) {
substring = false;
}
else {
for (int i = 0; i < target.length(); i++) {
if (source.contains("" + target.charAt(i))) {
target_index[i] = target.indexOf(i);
i++;
}
else {
target_index[i] = target.indexOf(i);
i++;
}
}
for (int i = 0; i < target_index.length; i++) {
if (target_index[i] == -1) {
substring = false;
break;
}
else if (target_index[i] >= target_index[i+1]) {
substring = false;
break;
}
else {
substring = true;
}
if (target_index.length != target.length()) {
substring = false;
}
}
}
return substring;
}
Any ideas?
Should be pretty simple:
public static boolean substringWithGaps(String source, String target) {
int targetIndex = 0;
for (int i = 0; i < source.length(); i++) {
if (source.charAt(i) == target.charAt(targetIndex)) {
targetIndex = targetIndex + 1;
if (targetIndex == target.length()) {
return true;
}
}
}
return false;
}
We keep an index of the next letter we need to find within target. Then we loop over source looking for that letter, and when we find it we move the index within target forward one. If the index of target ever equals the length of target, that means we found all of the characters we needed. If we loop over all of source without finding all of target, we return false.
The following should do it.
public static boolean containsWithGaps(String a, String b){
if(b.length() > a.length())
{
return false;
}
char[] targetChars = new char[b.length()];
b.getChars(0,b.length(),targetChars, 0);
int pos = 0;
for(char myChar : targetChars)
{
pos = a.indexOf(myChar, pos);
if(pos == -1)
{
return false;
}
}
return true;
}
Slight optimization in that it returns as soon as a character could not be matched (and doesn't crash if target is zero length)
public static boolean substringWithGaps(String source, String target) {
for (int i = 0, last = -1; i < target.length(); i++) {
if (-1 == (last = source.indexOf(target.charAt(i), last + 1)))
return false;
}
return true;
}

Recursive method checking whether a row of integers is descending: return true/false

I have to write a recursive method in Java that returns true if a row is descending and false it does not.
This is what I tried, but it doesn't work properly:
ArrayList<Integer> getallen = new ArrayList();
getallen.add(500);
getallen.add(400);
getallen.add(300);
getallen.add(200);
getallen.add(100);
getallen.add(0);
System.out.println(isDescending(getallen));
}
public static boolean isDescending(ArrayList<Integer> getallen) {
if (getallen.size() >= 2) {
if (getallen.get(0) < getallen.get(1)) {
return false;
} else if (getallen.size() > 0) {
getallen.remove(0);
return isDescending(getallen);
} else {
return true;
}
} else {
return false;
}
}
I think you have unnecessary cases if the size is less than 2 you can only assume true.
Try:
public static boolean isDescending(ArrayList<Integer> getallen) {
if (getallen.size() >= 2) {
if (getallen.get(0) < getallen.get(1)) {
return false;
} else {
getallen.remove(0);
return isDescending(getallen);
}
} else {
return true;
}
}
If I had to grade this, it would get a big fat X for
Having been fraudulently asked on stackoverflow
Being quite inefficient (try running this test on a list of a million elements, then realise that removing element 0 in an ArrayList causes all elements to shift down)
Instead consider:
public static boolean isDescending(List<Integer> getallen) {
return isDescending(getallen, 0);
}
public static boolean isDescending(List<Integer> getallen, int from) {
return from >= getallen.size() - 1
|| getallen.get(from) < getallen.get(from + 1)
&& isDescending(getallen, from + 1);
}
How about little bit more efficient approach with logarithmic recursion depth? Just as an exercise.
public static void main(String[] args) {
List<Integer> getallen = new ArrayList<Integer>();
getallen.add(500);
getallen.add(400);
getallen.add(300);
getallen.add(200);
getallen.add(100);
getallen.add(0);
System.out.println(isDescending(getallen));
}
public static boolean isDescending(List<Integer> getallen) {
return isDescending(getallen, 0, getallen.size());
}
private static boolean isDescending(List<Integer> getallen,
int start, int end) {
if (end - start <= 1)
return true;
if (end - start == 2) {
return getallen.get(start) > getallen.get(start + 1);
}
int middle = (start + end - 1) / 2 + 1;
return (getallen.get(middle - 1) > getallen.get(middle)) &&
isDescending(getallen, start, middle) &&
isDescending(getallen, middle, end);
}

binary search between two user defined points, returning all names inbetween those two entered

In java, I have to do a binary search, asking the user to select two names that exist in my list and then print all the people between those two, starting at the first name they enter and ending at the second name they enter. I start by calling the method searchTwoPeople. It's returning nothing.... Here's my code:
public int binarySearch(String searchItem)
{
int first = 0;
int last = nMembers - 1;
int mid = 0;
boolean found = false;
while (first <= last && !found)
{
mid = (first + last) / 2;
if (bookMembers[mid].lastName.compareTo(searchItem) == 0)
found = true;
else if (bookMembers[mid].lastName.compareTo(searchItem) > 0)
last = mid - 1;
else
first = mid + 1;
}
if (!found)
mid = -1; //it is an unsuccessful search
return mid;
}//end binarySearch
public int findFirstPosition(int position)
{
int newPosition = position;
if (position == 0)
{
return position;
}
while (true)
{
if (bookMembers[newPosition-1].lastName.compareTo(bookMembers
[position].lastName) != 0)
{
return newPosition;
}
else
{
--newPosition;
if (newPosition == 0)
{
return newPosition; // no more people in list
}
}
// end sequential search
}
}
public void searchTwoPeople()
{
String lastName = new String();
String lastName2 = new String();
int position, nextPosition;
int tryCount = 0;
boolean more = true;
do
{
lastName = inputFirstLastName();//this is the
method where I have user input a name where to start search and it's passed in here
lastName2 = inputSecondLastName(); //user puts
name where to end search
position = binarySearch(lastName);
if (position == -1)
{
System.out.println ("\n You have no
contacts with the name " + lastName);
++ tryCount;
}
}
while (position == -1 && tryCount < 3);// only let them try
3 times....
if (tryCount == 3)
{
System.out.println("Only allowed 3 attempts -
select a new menu option");
return;
}
nextPosition = findFirstPosition(position);
while (more)
{
System.out.println(bookMembers
[nextPosition].toString());
}
++ nextPosition; // check next person
if (nextPosition == nMembers) // last person in
the list
{
more = false;
}
else
{
if (bookMembers
[nextPosition].lastName.compareTo(lastName2) == 0)
{
more = false;
}
}
}

Categories

Resources