overflow with binary search recursively c++ - c++

I am trying to implement binarySerach recursively, but I got stack overflow.
First I have find function that takes 3 parameters. Then I call this function in main and pass adresess from the array. Nut I have got stack overflow!
bool find( const int x, const int* pBegin, const int* pEnd)
{
int medel =((*pBegin) + (*pEnd -1))/2 ;
if(x == medel)
return true ;
else if( x<medel)
{
int last = medel -1 ;
return find(x, pBegin, &last);
}
else if( x > medel)
{
int begin = medel +1;
return find(x, &begin, pEnd);
}
}// find
void main()
{
int arr[10];
for (int i=0;i<10;++i)
arr[i] = i;
bool found = find(3, &arr[0], &arr[10]);
cout << "hittat = " << found << endl;
system("pause");
}

There are several very fundamental issues around the use of pointers in your code. Without fixing the code for you, I'll give you a hint:
Try turning medel into a pointer to the middle element. This might help resolve some of the confusion.

Related

recursive binary search in c++ using a bool function

I have an school assignement that requires me to create a recursive Binary search function. I'm not allowed to change the function signature.
My experience with pointer isn't the best and i think my problem lies there.
I get an Stackoveflow but i dont really understand way
bool contains(const int* pBegin, const int* pEnd, int x)
{
int length = pEnd - pBegin;//gives me the length of the array
const int* pMid = pBegin + (length / 2);
if(length == 1)
{
if(*pMid != x)
return false;
return true;
}
else if(x < *pMid)
return contains(pBegin, pMid-1, x);
else
return contains(pMid, pEnd, x);
}
void main(){
setlocale(LC_ALL, "swedish");
int arr[10];
for(int i = 0; i < 10; ++i)
arr[i] = i;
bool find = contains(&arr[0], &arr[10], 3);//arr[10] points to the index after the array!
cout <<"found = "<< find << endl;
system("pause");
}
Can somebody please explain to me what I'm doing wrong, and how i could do it in a better way?
Stack overflow is due to too deep recursion.
Its unlikely your array is large enough to really be a problem, so what you have is unbounded recursion ... contains() keeps calling itself and fails to detect this.
Look at how this is possible, and add assertions.
Your code assumes
pEnd > pBegin
Your code doesn't handle this possibility.
#include <assert.h>
bool contains( ... )
{
assert(pBegin > pEnd);
...
Now, it will abort if this assumption is incorrect.
There are two possibities for (pEnd > pBegin) being false, namely "<" or "==".
What does your code do in these two cases?
Spoiler below..
Length can be zero and isn't handled.

Messy and wrong char visualization (after passing actual parameters) C++

this is my first post. Below the code of my implementation of a char Stack. Theoretically It should print f,g,h. But when I execute it, I can just see a long list of strange signs in the console. Is a compiler issue or code issue? Thanks.
#include <iostream>
using namespace std;
const int max_L = 10;
class Stack {
protected:
char array[];
int length;
public:
Stack(){length = 0;}
bool push(char c) {
if(length < max_L){
array[length] = c;
length++;
return(true);
}
else return(false);
}
void pop(){
if(length >= 1){
cout << array[length];
length--;
} else return ;
}
bool is_empty(){
return(length == 0);
}
void print(){
for(int i = 0; i < length; i++){
cout << array[i];
}
}
};
int main() {
Stack p1;
p1.push('f');
p1.push('g');
p1.push('h');`
p1.print();
return 0;
}
There are two problems in the code. As πάντα ῥεῖ said, the array has to be created with a size. The other problem is that push and pop aren't quite complementary. push puts the added value at array[length], then increments length. So after a call to push, length is the index of the next entry, i.e., the one that hasn't been put in yet. pop has to look at the previous entry, i.e., the one that was just put in. So the code for pop should decrement length before looking at array[length]. Change
cout << array[length];
length--;
to
length--;
cout << array[length];

Searching a string inside a char array using Divide and Conquer

Let's say that I have a struct array and each element has a name. Like:
struct something{
char name[200];
}a[NMAX];
Given a new string (char array), i need to find the correct index for it using divide and conquer. Like:
char choice[200];
cin>>chioce;
int k=myFunction(choice); // will return the index, 0 otherwise
// of course, could be more parameters
if( k )
cout<<k;
I don't know how to create that searching function (I tried, I know how D&C works but i'm still learning! ).
And no, i don't want to use strings !
This is what i tried:
int myFunction(char *choice, int l,int r) // starting with l==0 && r==n-1
{
int m;
if(strcmp(a[m].name,choice)==0)
return m;
else{
m=(l+r)/2;
return myFunction(choice,l,m-1);
return myFunction(choice,m+1,r);
}
}
This is my solution for your above problem. But i have modified a few things in your code.
#include<iostream>
using namespace std;
#define NMAX 10
struct something{
char *name; //replaced with char pointer so that i can save values the way i have done
}a[NMAX];
int myFunction(char *choice, int l,int r) // starting with l==0 && r==NMAX-1
{
if(l>r) //return if l has become greater than r
return -1;
int m=(l+r)/2;
if(strcmp(a[m].name,choice)==0)
return m+1;
else if(l==r) //returned -1 as the value has not matched and further recursion is of no use
return -1;
else{
int left= myFunction(choice,l,m-1);//replaced return
int right= myFunction(choice,m+1,r);//by saving values returned
if(left!=-1) //so that i can check them,
return left; //otherwise returning from here onlywould never allow second satatement to execute
if(right!=-1)
return right;
else
return -1;
}
}
int main(){
a[0].name="abc";
a[1].name="a";
a[2].name="abcd";
a[3].name="abcf";
a[4].name="abcg";
a[5].name="abch";
a[6].name="abcj";
a[7].name="abck";
a[8].name="abcl";
a[9].name="abcr";
char choice[200];
cin>>choice;
int k=myFunction(choice,0,NMAX-1); // will return the index, 0 otherwise
// of course, could be more parameters
if( k !=-1)
cout<<k;
else
cout<<"Not found";
return 0;
}
Hope it will help.

Sorted list: must have class/struct/union

so i have been working on a code for over two weeks and its not going too well. here are the instructions and the code is below it, as well as errors:
Task 1: Create one instance of this class. (the sorted list; he also had other instructions on HOW to start the code, but its already been done by me below in the code such as typedef...) You also need to read in data from one data file: float.dat, which contains the following numbers:
5.5
6.2
7.1
8.0
9.0
10.0
1.0
2.0
3.3
4.4
Data in float.dat contains floating numbers, which should be inserted into the object of SortedList. Note that you do not have any prior knowledge about data values in float.dat, but we assume that there are 10 elements in the data file.
Task 2: Use GetNextItem( ) to print out all the elements in the list in sorted sequence on computer screen.
Task 3: Use GetNextItem( ) to output all the elements in the list in sorted sequence onto a data file, output.dat.
Task 4: Design your test cases to demonstrate InsertItem( ), DeleteItem( ) and RetrieveItem( ) are working as expected.
here is the code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#define MAX_ITEMS 10
typedef float ItemType;
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList() {length = 0; currentPos = -1;}
int getLength() {return length;}
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
void MakeEmpty() {length = 0;}
void InsertItem(ItemType x)
{
int first = 0, last = length --;
bool moreToSearch = (first <= last);
int location = 0;
int midpoint= (first + last) / 2;
while (moreToSearch)
{
switch (x.ComparedTo(values[location]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
break;
case GREATER:
location++;
moreToSearch = (location < length);
break;
}
}
for (int index = length; length > location; index--)
{
values[index] = values[index - 1];
}
values[location] = x;
length++;
}
void DeleteItem(ItemType x)
{
int location = 0;
while (x.ComparedTo(values[location]) != EQUAL)
location++;
for (int index = location ++; index < length; index++)
values[index --] = values[index];
length--;
}
void RetrieveItem(ItemType &x, bool & found)
{
int midpoint;
int first = 0, last = length - 1;
bool moreToSearch = (first <= last);
found = false;
int index = 0;
while (moreToSearch && !found)
{
midpoint = (first + last) / 2;
switch (x.ComparedTo(values[index++]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
last = midpoint - 1;
break;
case GREATER: //Search in 2nd half
first = midpoint + 1;
moreToSearch = (first <= last);
break;
case EQUAL: //x has been found
found = true;
break;
}
}
}
int LengthIs() {return length;}
void ResetList() {currentPos = -1;}
bool IsFull()
{
if (length < 9)
return false;
else
return true;
}
void GetNextItem(ItemType &x)
{
currentPos++;
x = values[currentPos];
cout << x;
}
};
int main()
{
SortedList x;
ifstream inFile; ofstream output;
string line;
bool allAboutLists;
int i = 0;
int size = 0;
inFile.open("float.txt");
float values[10];
while (!inFile.eof()) // write or read data from inFile into values
{
inFile >> values[i];
i++;
size++; // this will count how many values there are in the array
x.InsertItem(values[i]);
++i;
}
x.ResetList();
cout << "The following is the list that's been made:" << endl << endl;
x.InsertItem(64);
//x.printlist();
cout << endl;
x.DeleteItem(64);
//x.printlist();
x.RetrieveItem(7.1, allAboutLists);
cout << endl;
cout << endl << "The length is: "; x.LengthIs(); cout << endl;
cout << "Is the list full?: " << boolalpha << x.IsFull() << endl;
cout << "The next item is: ";
for (int i = 0; i < 10; i++)
{
cout << x.GetNextItem << endl;
}
x.ResetList();
inFile.close();
output.open("output.txt");
for (int f = 0; f < 10; f++)
{
output << x.GetNextItem << endl;
}
system("pause");
return 0;
}
and the compiler keeps saying this:
(25) error C2228: left of '.getLength' must have class/struct/union [they mean the x. its red lined under, same for the rest of those left of etc..]
(27) error C2228: left of '.getLength' must have class/struct/union
(44) error C2228: left of '.ComparedTo' must have class/struct/union
(66): error C2228: left of '.ComparedTo' must have class/struct/union
-and also, 7.1 in main has something about refernce type mistake.
I am in extereme hurry as i have been working on it for 2 weeks now and its driving me crazy ! I have the code done as seen and more than wnough and just need to know what to change exactly because I am following everything I have been searching and researching yet its no good. so precise details or code specifically taken from mine and fixed would be appreciated.
Thanks!
You are passing x as ItemType which is a float.
float doesn't have those methods... looks like you wanted to pass it as a SortedList
The compare function needs two parameters in order to do a compare. Instead of ComparedTo, you may want to call it CompareToLocation.
RelationType CompareToLocation(ItemType x, size_t location){
if(x < values[location]) return LESS;
if(x == values[location]) return EQUAL;
return GREATER;}
An example usage would be:
result = CompareToLocation(x, location);
// ...
You defined ComparedTo as a method for SortedList, yet everytime you call that function, you call it on ItemType objects, which are actually floats.
As you can see in the definition of the method, you are trying to use, once again, SortedList methods on float Objects:
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
Your problem is not really a compiling one, but a conceptual one, since you don't seem to grasp what your are actually coding.
I'd recommend have your declarations and implementations separate, so you can see at a glance how does your class work.
Your class declaration should look something like this:
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList();
int getLength();
RelationType ComparedTo(ItemType x) ;
void MakeEmpty();
void InsertItem(ItemType x) ;
void DeleteItem(ItemType x);
void RetrieveItem(ItemType &x, bool & found);
int LengthIs();
void ResetList();
bool IsFull();
void GetNextItem(ItemType &x);
};
You should focus on each method, making clear what each one of them is trying to achieve, and what does it need to achieve it (parameters).
For example:
RelationType ComparedTo(ItemType x) ;
Your SortedList class has this function, which receives an ItemType (float) as a parameter.
What is this trying to achieve? How do you compare a whole ordered list to a single element?
How can a single number be greater, less or EQUAL to a set of numbers?
Maybe what you really want to do is compate parameter X with an element inside the list?
If this is the case, how do you know which element in the list must be compared to parameter X? You should add another parameter telling you which element inside your ordered list to compare X to.
I quess this doesn't really solve your problem, but at least I hope this helps you understand better what your problem is.

Learning recursion: How can I locate a substring index within a string without using find?

I have a recursive function to find the starting index of a substring within a string. I am learning to use recursion, so the find function is not allowed. I believe I have met most of the conditions. This function is supposed to find the correct index in the string. If it is blank it returns -1.
Here is the real problem. If I enter a string "nothing" and search for "jax" it doesn't return -1. I don't understand why. Any help please? Here is the code:
The user would enter string s and t passed into below:
int index_of(string s, string t)
{
int start = 0;
int len2 = t.length();
int index = 0;
if (s == "")
{
return -1;
}
else if (s.substr(1).length() <= t.length())
{
return -1;
}
else if ( s.substr(start, len2) == t)
{
return index;
}
else
{
index ++;
return index + index_of(s.substr(1), t);
}
return -1;
}
There are several problems -- some minor ones, and some quite important ones.
You have two variables, start and index, to indicate "the current position", but one would be enough.
index can only be 0 or 1. Therefore, the way it is currently written, you could easily get rid of index and start altogether.
Important: When, during the final recursion, the end of the string is reached, you return -1 to the previous recursive call. Then, because of the way the recursive calls are done, you add 1 and return that to the previous call, and so forth. The value finally returned is the -1 plus the length of the string. That is why you get strange results.
This comparison
if (s.substr(1).length() <= t.length())
does not make much sense.
Taking all of this into account, here is an improved version:
#include <iostream>
#include <string>
int index_of(
const std::string &s,
const std::string &t,
const size_t index)
{
int len2 = t.length();
if ((s.length() - index) < t.length())
return -1;
else if (s.substr(index,len2) == t)
return index;
else
return index_of(s,t,index + 1);
return -1;
}
/** Overloading, so you can call index_of with just
two arguments */
int index_of(const std::string &s, const std::string &t)
{
return index_of(s,t,0);
}
/** Some test cases. */
int main()
{
std::cout << index_of("hello","ello") << std::endl;
std::cout << index_of("nothing","jax") << std::endl;
std::cout << index_of("hello","llo") << std::endl;
std::cout << index_of("hello","lo") << std::endl;
std::cout << index_of("hello","o") << std::endl;
std::cout << index_of("hello","hel") << std::endl;
}
The best way to learn how to debug problems like this is to work them out on paper. Your example is small enough that it shouldn't take too long. It's pretty clear that you're going to fall into your else case in the first few steps because the strings don't match. So we have:
index_of("nothing", "jax"):
index++; // index is now 1
return 1 + index_of("othing", "jax");
index_of("othing", "jax"):
index++; // index is now 1
return 1 + index_of("thing", "jax");
etc.
Does that help?