Creating a function using the binary search - c++

I am trying to use a function to find a number in an array using the binary search. The code runs in visual studio community but does not work in code blocks. It just shows found.Would appreciate if some could point out why it's not working. This is the function
void sort(int array[7],int num)
{
int left=0,right=7;
while (left<=right)
{
int mid = (left+right)/2;
if(array[mid]==num)
{
cout<<"found";
break;
}
else if(num<array[mid])
right = mid-1;
else
left = mid+1;
}
if(left > right) cout<<"not found";
}

When you write, int array[7], then you create an array which can be indexed 0..6. Therefore, you should use right = 6.
Also, be very careful when you write right = mid - 1 or left = mid + 1. You need to be sure that the new values are within 0..6. E.g., left == 0, right == 1, mid == 0 - after this, you say right = - 1. That's not ok, you need boundary checks.

Related

diameter of a Binary tree recursive approach

I am trying to find diameter using recursion ,I am confused with recursion
some of the test cases I tried I got correct answer at some point
Integer overflow occured But Below author's solution was accepted with same data types
My approach:
For every node, length of longest path which pass it = MaxDepth of its left subtree + MaxDepth of its right subtree.
My question is whats wrong with my implementation
class Solution {
public:
int mx = 0;
int solve(TreeNode* root) {
if (root == NULL)return 0;
int leftheight = diameterOfBinaryTree(root->left) + 1;
int rightheight = diameterOfBinaryTree(root->right) + 1;
mx = max(mx, leftheight + rightheight);
return max(leftheight, rightheight);
}
int diameterOfBinaryTree(TreeNode* root) {
solve(root);
return mx;
}
};
Authors approach: same approach but different recursion implementation
class Solution {
public:
int maxdiadepth = 0;
int dfs(TreeNode* root) {
if (root == NULL) return 0;
int leftdepth = dfs(root->left);
int rightdepth = dfs(root->right);
if (leftdepth + rightdepth > maxdiadepth) maxdiadepth = leftdepth + rightdepth;
return max(leftdepth + 1, rightdepth + 1);
}
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return maxdiadepth;
}
};
In the working implementation, the recursive dfs call returns the max depth of the subtree.
In your implementation, the recursive diameterOfBinaryTree call returns the currently accumulated approximation to the diameter. You assign it to variables named leftheight and rightheight - that's misleading; the value is not, in fact, the height of the left or right sub-tree.
Consider the case when you hit a leaf node or the case where you have only one node. Your algorithm returns 2, which is incorrect. This problem arises because you compute the height by adding one to the left / right subtree, no matter what.
To fix this, add one when you return the height, like so: max(leftheight, rightheight) + 1
Btw, when you recursively call, you should do solve(root->left) or solve(root->right) and not diameterOfBinaryTree(root->left) :P

Understanding a recursive Binary Search Algorithm that mysteriously works [duplicate]

This question already has answers here:
Why does flowing off the end of a non-void function without returning a value not produce a compiler error?
(11 answers)
Closed 4 years ago.
On an assignment I had to make a recursive binary search algorithm output the index instead of True/False without modifying the parameters. I had a really tough time but after resorting to semi-trial-and-error I stumbled upon this mess:
#include <iostream>
#include <math.h>
#include <climits>
using namespace std;
int BinarySearch(int arr[], int len, int target) {
int temp = 0;
int mid = len/2;
if (len <= 0) return INT_MIN; // not found
if (target == arr[mid]){
return mid; // found
}
if (target < arr[mid]){
temp = BinarySearch(arr, mid, target);
}
else {
temp = mid+1 + BinarySearch(arr+mid+1, len-mid-1, target);
}
}
I have literally no idea why it works, even after running it through a visualizer. It's very sensitive to the code being changed and I can't get it to output -1 when it fails to find the target so I made it at least always output a negative number instead.
I don't really need it fixed, I just want to know how it even works since seemingly none of the recursive call's outputs are even used. Thanks.
It is undefined behaviour (see e.g. Why does flowing off the end of a non-void function without returning a value not produce a compiler error?).
The compiler appears to return temp by chance, likely because it is the first local variable declared inside the function. Returning temp would fix it.
As far as I understand you want to return -1, if the target is not found and the index of the target otherwise. In
if (len <= 0) return INT_MIN; // not found
you are returning INT_MIN, if the target is not found. You need to change it to
if (len <= 0) return -1; // not found
Since your function returns an int value, it has to return something on each patch. You can fix it by adding the return at the end of the function:
if (target < arr[mid]){
temp = BinarySearch(arr, mid, target);
}
else {
temp = mid+1 + BinarySearch(arr+mid+1, len-mid-1, target);
}
return temp;
}
BinarySearch returns the index of target in the current arr. Since the current arr often doesn't begin with index 0, you're adding and subtracting mid+1. You're also doing it, if the target was not found and BinarySearch returns -1. You have to fix the else part:
else {
int index(BinarySearch(arr+mid+1, len-mid-1, target));
temp = index == -1 ? -1 : mid + 1 + index;
}

How does the Hill Climbing algorithm work?

I'm learning Artificial Intelligence from a book, the book vaguely explains the code I'm about to post here, I assume because the author assumes everyone has experienced hill climbing algorithm before. The concept is rather straightforward, but I just don't understand some of the code below and I'd like someone to help me understand this algorithm a bit clearer before I move on.
I commented next to the parts that confuses me most, a summary of what these lines are doing would be very helpful to me.
int HillClimb::CalcNodeDist(Node* A, Node* B)
{
int Horizontal = abs(A->_iX - B->_iX);
int Vertical = abs(A->_iY - B->_iY);
return(sqrt(pow(_iHorizontal, 2) + pow(_iVertical, 2)));
}
void HillClimb::StartHillClimb()
{
BestDistance = VisitAllCities();
int CurrentDistance = BestDistance;
while (true)
{
int i = 0;
int temp = VisitAllCities();
while (i < Cities.size())
{
//Swapping the nodes
Node* back = Cities.back();
Cities[Cities.size() - 1] = Cities[i];
Cities[i] = back; // Why swap last city with first?
CurrentDistance = VisitAllCities(); // Why visit all nodes again?
if (CurrentDistance < BestDistance) // What is this doing?
{
BestDistance = CurrentDistance; //???
break;
}
else
{
back = Cities.back();
Cities[Cities.size() - 1] = Cities[i];
Cities[i] = back;
}
i++;
}
if (CurrentDistance == temp)
{
break;
}
}
}
int HillClimb::VisitAllCities()
{
int CurrentDistance = 0;
for (unsigned int i = 0; i < Cities.size(); i++)
{
if (i == Cities.size() - 1)//Check if last city, link back to first city
{
CurrentDistance += CalcNodeDist(Cities[i], Cities[0]);
}
else
{
CurrentDistance += CalcNodeDist(Cities[i], Cities[i + 1]);
}
}
return(CurrentDistance);
}
Also the book doesn't state what type of hill climb this is. I assume it's basic hill climb as it doesn't restart when it gets stuck?
Essentially, it does this in pseudo-code:
initialize an order of nodes (that is, a list) which represents a circle
do{
find an element in the list so that switching it with the last element of the
list results in a shorter length of the circle that is imposed by that list
}(until no such element could be found)
VisitAllCities is a helper that computes the length of that circle, CalcNodeDist is a helper that computes the distance between two nodes
the outer while loop is what I called do-until, the inner while loop iterates over all elements.
The if (CurrentDistance < BestDistance) part simply checks whether changing that list by swapping results in a smaller length, if so, update the distance, if not, undo that change.
Did I cover everything you wanted to know? Question about a particular part?

Buggy simple function for binary search (C++)

I wrote a simple function for binary search, but it's not working as expected. I have a vector with 4000000 32-bit ints. Usually, when I search for a number, if it's there, it's found and the index is returned, if it's not, -1 is returned (the index always corresponds to the value, but that's not the point).
While messing around with the program I found out that it can't find 93 (even though it's there), obviously, there must be more values it can't find.
I use CLion, which implements GDB as the debugger and G++ as the compiler.
template<typename T>
int BinarySearch(vector<T>& vec, T& request)
{
int low = 0;
int high = vec.size() - 1;
while (low < high)
{
int mid = (low / 2 ) + (high / 2); // Styled it this way to avoid overflows.
// This looks like where the bug happens, basically low and high both
// become 93 while mid becomes 92,
// it then exits the loop and returns -1 because low is not lower than
// high anymore.
if (vec[mid] == request)
{
return mid;
}
else if (vec[mid] < request)
{
low = mid + 1;
}
else if (vec[mid] > request)
{
high = mid - 1;
}
}
return - 1;
}
I'm pretty confused by this, what's wrong?
Condition should be while (low <= high).
If you keep it as while (low < high), then when low==high (means we reach the final element), while loop will break and will return -1. So,your program wont check that element.
Also you should use mid=low+(high-low)/2; to prevent overflow and access all values.Problem in your code is that suppose when low=high=1, it will give mid =0(due to data conversion), which is wrong.

Binary Search avoid unreadable entry (hole in list)

I have implemented a binary search function but I have an issue with a list entry that may become unreadable. It's implemented in C++ but ill just use some pseudo code to make it easier. Please to not focus on the unreadable or string implementation, it's just pseudo code. What matter is that there are unreadable entries in the list that have to be navigated around.
int i = 0;
int imin = 0;
int imax = 99;
string search = "test";
while(imin <= imax)
{
i = imin + (imax - imin) / 2;
string text = vector.at(i);
if(text.isUnreadable())
{
continue;
}
if(compare(text, search) = 0)
{
break;
}
else if(compare(text, search) < 0)
{
imin = i + 1;
}
else if(compare(text, search) > 0)
{
imax = i - 1;
}
}
The searching itself is working pretty well, but the problem I have is how to avoid getting an endless loop if the text is unreadable. Anyone has a time tested approach for this? The loop should not just exit when unreadable but rather navigate around the hole.
I had similar task in one of projects - lookup on sequence where some of items are non-comparable.
I am not sure is this the best possible implementation, in my case it looks like this:
int low = first_comparable(0,env);
int high = last_comparable(env.total() - 1,env);
while (low < high)
{
int mid = low + ((high - low) / 2);
int tmid = last_comparable(mid,env);
if( tmid < low )
{
tmid = first_comparable(mid,env);
if( tmid == high )
return high;
if( tmid > high )
return -1;
}
mid = tmid;
...
}
If vector.at(mid) item is non-comparable it does lookup in its neighborhood to find closest comparable.
first/last_comparable() functions return index of first comparable element from given index. Difference is in direction.
inline int first_comparable( int n, E& env)
{
int n_elements = env.total();
for( ; n < n_elements; ++n )
if( env.is_comparable(n) )
return n;
return n;
}
Create a list of pointers to your data items. Do not add "unreadable" ones. Search the resulting list of pointers.
the problem I have is how to avoid getting an endless loop if the text is unreadable.
Seems like that continue should be break instead, so that you break out of the loop. You'd probably want to set a flag or something to indicate the error to whatever code follows the loop.
Another option is to throw an exception.
Really, you should do almost anything other than what you're doing. Currently, when you read one of these 'unreadable' states, you simply continue the loop. But imin and imax still have the same values, so you end up reading the same string from the same place in the vector, and find that it's unreadable again, and so on. You need to decide how you want to respond to one of these 'unreadable' states. I guessed above that you'd want to stop the search, in which case either setting a flag and breaking out of the loop or throwing an exception to accomplish the same thing would be reasonable choices.