Recursive binary search with three arguments in C++ - c++

I'm trying to get this recursive binary search right and got this far. So far I can get the first half to be shown correctly, but the right side of mid is shown as if it where the left side. Where could I be wrong?
#include <iostream>
using namespace std;
int binarySearch(int array[], int size, int searchValue)
{
cout << "BST with size = " << size << "[ ";
for (int i = 0; i < size; ++i){
cout << array[i] << " ";
}
cout << " ]" << endl;
if (size >= 1)
{
int mid = (size - 1) / 2;
cout << "Mid " << mid << endl;
if (array[mid] == searchValue)
{
return mid;
}
if (array[mid] > searchValue)
{
return binarySearch(array, mid, searchValue);
}
if (array[mid] < searchValue)
{
return binarySearch(array+mid+1, size-(mid + 1), searchValue);
}
}
return -1;
}
int main() {
int val, myNums[1000]; // Yuck--magic number!
int pos, cnt = -1;
cout << "Enter numbers from smallest to largest, 0 to stop\n";
do {
cin >> myNums[++cnt];
} while (myNums[cnt] != 0);
do {
cout << "Enter number to search for: ";
cin >> val;
if (val != 0) {
pos = binarySearch(myNums, cnt, val);
cout << "binarySearch reported " << pos << endl;
}
} while (val != 0);
return 0;
}

This code is not correct with a very error - you're trying to get the offset of a value in some fixed array, but you do manipulate that array here:
return binarySearch(**array+mid+1**, size-(mid + 1), searchValue);
You can clearly see that this function doesn't work, because array+mid+1, in case of the 1st element after the mid, will return 0, while it's supposed to return:
(int)(size/2)+1
I suggest you pass 'start' and 'end' range variables to the function.
Also this text:
cout << "BST with size = " << size << "[ ";
T in BST stands for 'Tree', but you do not create any tree.

Instead of this part:
if (array[mid] < searchValue)
{
return binarySearch(array+mid+1, size-(mid + 1), searchValue);
}
You can use:
if (array[mid] < searchValue)
{
int ans = binarySearch(array+mid+1, size-(mid + 1), searchValue);
if (ans == -1)
return -1;
return mid + ans + 1;
}

Related

BinarySearch not working for reversed array

I am working on a project for school that tests Binary Search vs. Linear Search. My LinearSearch method seems to work fine when the array is in either increasing order or reversed. However, the BinarySearch only works when the array is in increasing order, but fails to work when the array is reversed. I am not sure what is causing this and would appreciate any suggestions/solutions.
Here is my code
/*
* SearchTest.cpp
*
* Created on: Oct 16, 2022
* Author: JH
*/
#include <iostream>
#include <time.h>
using namespace std;
//BinarySearch method
int BinarySearch(int numbers[], int numbersSize, int key) {
int mid;
int low;
int high;
low = 0;
high = numbersSize - 1;
while (high >= low) {
mid = (high + low) / 2;
if (numbers[mid] < key) {
low = mid + 1;
}
else if (numbers[mid] > key) {
high = mid - 1;
}
else {
return mid;
}
}
return -1; // not found
}
//LinearSearch method
int LinearSearch(int* array, int arraySize, int key) {
for (int i = 0; i < arraySize; i++) {
if (array[i] == key) {
return i;
}
}
return -1; // not found
}
//method to reverse array elements
void reverseArray(int arr[], int start, int end)
{
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
int main() {
//declare array
int reverseArr[1000];
int size = sizeof(reverseArr)/sizeof(reverseArr[0]);
//initialize array
for (int i = 0; i < size; i++) {
reverseArr[i] = i;
}
//reverse array
reverseArray(reverseArr, 0, size-1);
//print array
for (int i = 0; i < size; i++) {
cout << reverseArr[i] << " ";
}
cout << endl;
cout << endl;
//generate random number
srand(time(NULL));
int randomNum = rand() % 1000;
//print statements
cout << "[Linear vs. Binary Search]" << endl;
cout << "The target value is " << reverseArr[randomNum] << endl;
cout << endl;
//call BinarySearch method for array
cout << "Binary Search Test: " << endl;
int key1 = reverseArr[randomNum];
int keyIndex1 = BinarySearch(reverseArr, size, key1);
if (keyIndex1 == -1) {
cout << key1 << " was not found." << endl;
}
else {
cout << "Found " << key1 << " at index " << keyIndex1 << "." << endl;
}
cout << endl;
//call LinearSearch method for array
cout << "Linear Search Test: " << endl;
int key2 = reverseArr[randomNum];
int keyIndex2 = LinearSearch(reverseArr, size, key2);
if (keyIndex2 == -1) {
cout << key2 << " was not found." << endl;
}
else {
cout << "Found " << key2 << " at index ";
cout << keyIndex2 << "." << endl;
}
}

c++: searching an array

I am writing a program that's supposed to search an array that is filled by user input and return different output depending on whether or not another integer given by the user is in that array. the output is the index of the element.
e.g., suppose my array is {1, 2, 3}. using search(), if I enter 2, it should tell me that 2 is in the array and that its index value is 1.
But for some reason, this function only works correctly if I enter the very first element. This means that if I search for 1 in the array above, it will tell me that the index value is 0 like it's supposed to, but it won't do that for other elements.
My code is below. What am I doing wrong here?
#include <iostream>
using namespace std;
const int DECLARED_SIZE = 20;
void fillArray(int a[], int size, int& numberUsed);
int search(const int a[], int numberUsed, int target);
int search2(const int a[], int numberUsed, int target);
int main() {
int size;
cout << "Enter the array size: ";
cin >> size;
int arr[size], listSize, target;
fillArray(arr, size, listSize);
char ans;
int result;
do {
cout << "Enter a number to search for: ";
cin >> target;
cout << endl << endl;
result = search(arr, size, target);
if (result == -1) {
cout << target << " is not on the list." << endl << endl;
cout << "Search again? (y/n): ";
cin >> ans;
cout << endl << endl;
}
else {
cout << target << " is stored in array position " << result << "." << endl << endl;
cout << "Search again? (y/n): ";
cin >> ans;
cout << endl << endl;
}
} while ((ans != 'n') && (ans != 'N'));
cout << "End of program." << endl;
return 0;
}
void fillArray(int a[], int size, int& numberUsed) {
cout << "Enter up to " << size << " non-negative whole numbers." << endl;
cout << "Mark the end of the list with a negative number." << endl;
int next, index = 0;
cin >> next;
while ((next >= 0) && (index < size)) {
a[index] = next;
index++;
cin >> next;
}
numberUsed = index;
}
//searches an array that is filled by the user
//this is where i think i am struggling
int search(const int a[], int numberUsed, int target) {
int index = 0;
bool found = false;
while ((!found) && (index < numberUsed)) {
if (target == a[index]) {
found = true;
}
else {
index++;
}
if (found) {
return index;
}
else {
return -1;
}
}
return 0;
}
If you look at your search function you will see that it always returns at the bottom of the while loop. That's why you only find the first number. What you should do is return if you find the number but carry on if you don't. Like this (with some other simplifications of your code)
int search(const int a[], int numberUsed, int target) {
for (int index = 0; index < numberUsed; index++) {
if (target == a[index]) {
return index;
}
}
return -1;
}
In your while loop in your search function, you're doing:
if (found) {
return index;
} else {
return -1;
}
Which means if you didn't find your input, it immediately returns -1 instead of trying the next index. You should only return when you've visited all other indexes.

How to fix failed build with no errors

I'm really new to programming. I tried to make some sort of sorting application that sorts an array by swapping the values in the array. But when I try to build it, it just says build failed. Visual Studio doesn't give an error, so I'm kind of stuck. Could you help me out?
I've tried to increase the array size, and made sure there isn't any loop writing more integers to the array than is possible.
#include <iostream>
using namespace std;
int arr[10];
bool sorted = false;
int compare(int x, int y);
int cycle;
int compres;
int slot;
int main()
{
for (int c = 0; c < 5; c++)
{
cin >> arr[c];
}
while (cycle <= 5)
{
compres = compare(cycle, cycle + 1);
if (compres == 1)
{
slot = arr[cycle];
arr[cycle] = arr[cycle + 1];
arr[cycle + 1] = slot;
cout << arr[cycle] << " and " << arr[cycle + 1] << "swapped" << endl;
}
else if (compres == 0)
{
cout << arr[cycle] << " is equal to " << arr[cycle + 1] << endl;
}
else if (compres == -1)
{
cout << arr[cycle] << " and " << arr[cycle + 1] << "are already sorted" << endl;
}
else
{
cout << "(!) Compare issue." << endl;
}
cycle++;
}
for (int i = 0; i < 5; i++)
{
cout << arr[i];
}
}
int compare(int x, int y)
{
if (x > y) { return 1; }
if (x == y) { return 0; }
if (x < y) { return -1; }
}
Output log:
https://i.stack.imgur.com/6mw5d.png
I think something went wrong while creating the project...
I made a new one and copy-pasted the code, it worked.
Thanks for your answers!

Why my recursive function doesn't return the right value?

I'm implementing a binary search and the code is below, however, it doesn't print out the right answer buy it prints out correct answer inside the function body, so it makes me really confused.
#include <iostream>
using namespace std;
int research(int a[], int target, int lowIndex, int highIndex)
{
int finalIndex;
cout << lowIndex << " " << highIndex << endl;
int midIndex = (lowIndex + highIndex) / 2;
if (a[midIndex] == target)
{
finalIndex = midIndex;
cout << "The final index is: " << finalIndex << endl;
}
else
{
if (a[midIndex] < target)
{
research(a, target, midIndex + 1, highIndex);
}
else
{
research(a, target, lowIndex, midIndex - 1);
}
}
return finalIndex;
}
int main()
{
int* array = new int[1000];
for (int i = 0; i < 1000; i++)
{
array[i] = i + 1;
}
cout << research(array, 234, 0, 999) << endl;
return 0;
}
The line:
cout << "The final index is: " << finalIndex << endl;
prints out the right final index but the line
cout << research(array, 234, 0, 999) << endl;
doesn't, instead it prints out random number. Anyone know what is going wrong here? Thank you!
The only time you actually set finalIndex to anything is when a[midIndex] == target, so when you recurse you're returning the value of an uninitialised variable.
(The finalIndex variable isn't shared between function invocations - each invocation uses its own variable.)
You need to use the return value from the recursive calls:
if (a[midIndex] < target)
{
finalIndex = research(a, target, midIndex + 1, highIndex);
}
else
{
finalIndex = research(a, target, lowIndex, midIndex - 1);
}

Dynamic Programming - Word Break

I am trying to solve this Problem.The question is as follows
Given an input string and a dictionary of words, find out if the input string can be segmented into a space-separated sequence of dictionary words.
Dictionary is an array of strings.
My Approach is the following recursive fn with storing of the results of recursive calls. The output is fine but I see that the stored result is never used.
My solution is hopefully correct as it passed the test cases.But I would be great if I know whether DP is used.
The code is:
#include <iostream>
#include <string.h>
using namespace std;
int r[100][100] = {0}; //To Store the calculated values
bool searchWord(char q[], char D[][20], int start, int end) {
cout << "In Search Word Loop with " << start << " " << end << endl;
char temp[end - start + 1];
int j = 0;
for (int i = start; i <= end ; ++i) {
//cout << "Looping i " << i << endl;
temp[j] = q[i];
j++;
}
// cout << "For Word " << temp << endl;
for (int i = 0; i < 12; ++i) {
// cout << "Comparing with " << D[i] << endl;
if (!strcmp(temp, D[i])) {
cout << "Found Word" << temp << " " << D[i] << endl;
return 1;
}
}
return 0;
}
bool searchSentence(char q[], char D[][20], int qstart, int qend) {
cout << "In Search Sentence Loop" << endl;
if (r[qstart][qend] != 0) {
cout << "DP Helped!!!" << endl;
return 1;
}
if (qstart == qend) {
if (searchWord(q, D, qstart, qstart))
return 1;
else return 0;
}
if (qstart > qend) return 1;
int i;
for (i = qstart; i <= qend; i++) {
if (searchWord(q, D, qstart, i)) {
r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
if (r[i + 1][qend] == 1) return 1;
}
}
return 0;
}
int main() {
char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
char q[100] = "samsungmango";
int index = 0; char ch;
ch = q[0];
while (ch != '\0') {
index++;
ch = q[index];
}
if (searchSentence(q, D, 0, index - 1))
cout << "Yes" << endl;
else cout << "No" << endl;
}
Is recursion mandatory? I see, iterative DP-solution is easiest and compact:
#include <stdio.h>
#include <string.h>
int main() {
const char *D[] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango", NULL};
const char q[] = "samsungmango";
char dp[100];
short d_len[20];
memset(dp, 0, sizeof(dp));
dp[0] = 1; // 0 element is always reacheable
int i, j;
// compute dict string lengths
for(i = 0; D[i]; i++)
d_len[i] = strlen(D[i]);
// Compute splits using DP array
for(i = 0; q[i] != 0; i++)
if(dp[i]) // this index is reacheable
for(j = 0; D[j]; j++) // try to make next reacheable indexes
if(strncmp(&q[i], D[j], d_len[j]) == 0)
dp[i + d_len[j]] = 1; // That position is reacheable, too
// if EOLN(q) is reached, then yes
printf("Answer is %s\n", dp[i]? "YES" : "NO");
} // main
Your code is actually wrong. To fail your code, try input like "likeman"
Note that there are two different return values possible from function searchSentence, 0 or 1. So if you initialize the r array with 0 there's no guarantee it's a new state when r[x][y] = 0. Initialize r array with some impossible value like -1 or 2 for this program and test again. Now you can easily confirm that if r[qbegin][qend] != -1 then this state has already been checked so you can return r[qbegin][qend] from here
Updated code :
#include <iostream>
#include <string.h>
using namespace std;
int r[100][100]; //To Store the calculated values
bool searchWord(char q[], char D[][20], int start, int end)
{
cout << "In Search Word Loop with " << start << " " << end << endl;
char temp[end - start + 1];
int j = 0;
for (int i = start; i <= end ; ++i)
{
//cout << "Looping i " << i << endl;
temp[j] = q[i];
j++;
}
temp[j] = '\0';
//cout << "For Word " << temp << endl;
for (int i = 0; i < 12; ++i)
{
// cout << "Comparing with " << D[i] << endl;
if (!strcmp(temp, D[i]))
{
cout << "Found Word" << temp << " " << D[i] << endl;
return 1;
}
}
return 0;
}
bool searchSentence(char q[], char D[][20], int qstart, int qend)
{
cout << "In Search Sentence Loop" << endl;
if (r[qstart][qend] != -1)
{
cout << "DP Helped!!!" << endl;
return r[qstart][qend];
}
if (qstart == qend)
{
if (searchWord(q, D, qstart, qstart))
return 1;
else return 0;
}
if (qstart > qend) return 1;
int i;
for (i = qstart; i <= qend; i++)
{
if (searchWord(q, D, qstart, i))
{
r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
if (r[i + 1][qend] == 1) return 1;
}
}
return 0;
}
int main()
{
char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
char q[100] = "ilike";
int index = 0; char ch;
ch = q[0];
memset(r, -1, sizeof(r));
while (ch != '\0')
{
index++;
ch = q[index];
}
if (searchSentence(q, D, 0, index - 1))
cout << "Yes" << endl;
else cout << "No" << endl;
}
P.S : There are some redundant lines of codes but I didn't change them and I added a null character in the end of the character array temp in function searchWord