Non-working while loop & Messed up Binary Search - c++

For this program I have to fill an array with 20 random numbers (1-100), sort the array (descending) and then search for a random key value and output the position of that value if it is in the array. I am having 2 problems. First the while loop I have to exit the program is not working and I can not figure out why. Second my binary search is not returning a position value and I don't know why. This code will compile.
#include <iostream>
#include <ctime>
using namespace std;
int printArray(int *arr, int arraySize);
int fillArrayWithRandomNumbers(int *arr, int arraySize);
int bubbleSortDesc(int *arr, int arraySize);
int binarySearch(int *arr, int arraySize, int key);
int main()
{
int const arraySize = 20;
int arr[arraySize];
cout << "CMPSC 201-Extra Credit\n" << "This program fills an array, and then searches for a random key value." << endl <<endl;
char stopTheProgram = 'n';
do {
int key, result;
cout << "Unordered array:" << endl;
fillArrayWithRandomNumbers(arr, arraySize);
printArray(arr, arraySize);
cout << endl << "Array after a bubble sort : " <<endl;
bubbleSortDesc(arr, arraySize);
printArray(arr, arraySize);
key = rand()%100;
cout << endl <<"Searching for " << key << endl;
result = binarySearch(arr, key, arraySize);
if (result == -1)
{
cout << "Key " << key << " not found in the array" << endl;
}
else
{
cout << "Key " << key << " found at position " << result << endl;
}
cout << "Stop the program? (y/n) ";
cin >> stopTheProgram;
cout << endl;
} while (!(stopTheProgram == 'Y' || stopTheProgram == 'y'));
return 0;
}
int fillArrayWithRandomNumbers(int *arr, int arraySize)
{
srand((unsigned)time(NULL));
for (int i = 0; i<arraySize; i++)
{
arr[i] = (rand() % 100) + 1;
}
return *arr;
}
int printArray(int *arr, int arraySize)
{
for (int i = 0; i<arraySize; i++)
{
cout << arr[i] << " ";
}
return *arr;
}
int bubbleSortDesc(int *arr, int arraySize){
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return *arr;
}
int binarySearch(int arr[], int key, int arraySize)
{
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
int position, lowerBound = 0;
position = (lowerBound + arraySize) / 2;
while ((arr[position] != key) && (lowerBound <= arraySize))
{
if (arr[position] > key)
{
arraySize = position - 1;
}
else
{
lowerBound = position + 1;
}
position = (lowerBound + arraySize) / 2;
}
if (lowerBound <= arraySize)
{
position = 19 - position;
return position;
}
else {
return -1;
}
}
Solved: I now have fixed my problems with my binary search, and exiting my while loop. I am going to leave this here just in case anyone has my prof after me. So just to recap, this program fills an array with 20 random numbers (ranging 1-100), sorts the array in descending order and then creates a random key value (between 1-100). It then bubble sorts the array so it is in ascending order, uses a binary search to find the key value in the array and finally output the position of that key value if it is in the array.

I can see two issues with your code. First, you are shadowing the stopTheProgram variable. You define it once just before the do/while loop and initialize it to 'n'; Then once inside the do/while you define another stopTheProgram. This is a problem because of scoping. Inside the do/while loop the input from the user is assigned to the local stopTheProgram (defined in the do/while) but that ceases to exits outside the loop. So the while loop expression is always evaluated using the globally scoped stopTheProgram, which is set to 'n'. So remove the second definition. Second is an issue with the expression that controls the while loop. It always evaluates true. Draw a truth table if you can't visualize it. If stopTheProgram = 'Y' then the stopTheProgram != "Y" || stopTheProgram != 'y' is 0 || 1 which is always true. If stopTheProgram = 'y' then stopTheProgram != "Y" || stopTheProgram != 'y' is 1 || 0 which is always true. This works: while(!(stopTheProgram == 'Y' || stopTheProgram == 'y'))

Related

How to write partition for quicksort with C++

I am writing an algorithm in C++ where the user types how many numbers they want to be sorted, then the program generates an array of random numbers, and sorts them. It also displays how much time it took to sort.
It only works for some of the trials, even if I use the same input. For example, if I ask the program to sort an array of 20 numbers, one of three things will happen:
It will sort the array with no problems.
The algorithm will time out and the terminal will print "Segmentation fault: 11".
The algorithm will sort the numbers in the correct order, but one number will be replaced with a random negative number.
Here is my partition algorithm (the thing giving me trouble). I am choosing the first/left item as my pivot:
int partition(int arr[], int leftIndex, int rightIndex)
{
int i = leftIndex;
int j = rightIndex;
int pivotValue = arr[leftIndex];
while(i < j){
while(arr[i] <= pivotValue){
i++;
}
while(arr[j] > pivotValue && i < j){
j--;
}
if(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i - 1];
arr[i - 1] = arr[leftIndex];
arr[leftIndex] = temp;
return i - 1;
}
Here is my quicksort algorithm:
void quickSort(int arr[], int left, int right)
{
if (left < right)
{
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
return;
}
Here is where I call everything in main():
int main()
{
clock_t sTime, eTime;
int n;
cout << "Enter an array size: " << endl;
cin >> n;
cout << endl;
int originalArray[n];
cout << "Start generating random numbers..." << endl;
for(int index=0; index<n; index++){
originalArray[index] = (rand()%100)+1;
}
cout << "Original array values: ";
printArray(originalArray, n);
cout<<"\n\n";
//Makes a copy of the original array to preserve its original order
int quickArray[sizeof(originalArray)];
for(int i = 0; i < sizeof(originalArray); i++){
quickArray[i] = originalArray[i];
}
//Perform quicksort
sTime = clock();
quickSort(quickArray, 0, n-1);
eTime = clock();
printf("Sorted array by quickSort: ");
printArray(quickArray, n);
cout << "\nTotal CPU time used in quickSort: " << (double)(eTime-sTime) / CLOCKS_PER_SEC * 1000.0 << " ms" << endl;
cout << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int partition(int arr[], int leftIndex, int rightIndex)
{
int pivotIndex = leftIndex;
int pivotValue = arr[pivotIndex];
int i = leftIndex;
int j = rightIndex;
while(i < j){
while(arr[i] <= pivotValue){
i++;
if(i >= rightIndex) break;
}
while(arr[j] >= pivotValue){
j--;
if(j <= leftIndex) break;
}
if(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap
arr[pivotIndex] = arr[j];
arr[j] = pivotValue;
return j;
}
void quickSort(int arr[], int left, int right)
{
if (left < right)
{
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
return;
}
int main()
{
clock_t sTime, eTime;
int n;
cout << "Enter an array size: " << endl;
cin >> n;
cout << endl;
int originalArray[n];
cout << "Start generating random numbers..." << endl;
for(int index=0; index<n; index++){
originalArray[index] = (rand()%100)+1;
}
cout << "Original array values: ";
for(auto c: originalArray) {
cout << c << " ";
}
cout<<"\n\n";
//Makes a copy of the original array to preserve its original order
int quickArray[n];
for(int i = 0; i < n; i++){
quickArray[i] = originalArray[i];
}
//Perform quicksort
sTime = clock();
quickSort(quickArray, 0, n-1);
eTime = clock();
printf("Sorted array by quickSort: ");
for(auto c: quickArray) {
cout << c << " ";
}
cout << endl;
cout << "\nTotal CPU time used in quickSort: " << (double)(eTime-sTime) / CLOCKS_PER_SEC * 1000.0 << " ms" << endl;
cout << endl;
return 0;
}
There were several mistakes I've encountered. Firstly, I have added break statements in the while loops of partititon() method so that it breaks incrementing i or decrementing j if they exceeds the boundaries of the array. That was probably why you get segmentation fault sometimes.
Then I've changed the swapping part at the end of the partition and returned j. Probably this part was not erroneous, but I find this solution to be more readable.
Then I changed the part where you create the new array to int quickArray[n], you were creating the quickArray with sizeof(originalArray), which was wrong because it used to create an array with more elements. sizeof() returns (number of elements) * 4 since each int takes 4 bytes of memory.
Now, it should be working properly.
In addition, picking the first element as pivot can make your program work in O(n^2) time complexity in the worst case, try shuffling your array before sending it to the quicksort() function. By doing so, you can eliminate the worst case scenario.
I'm not sure if it's responsible for all the problems you're seeing, but I'd start with this bit of code:
while(i < j){
while(arr[i] <= pivotValue){
i++;
}
What's this (especially the inner loop) going to do if the pivot is the largest value in the array?

why my code is not giving the right fibonecci number in nth value

#include <iostream>
using namespace std;
int fibo(int);
int main()
{
int num;
cout << "Enter the nth position you want to find the fibonecci number\t ";
cin >> num;
cout << "The " << num << "th fibonecci number is " << fibo(num);
}
int fibo(int n)
{
int j = 0;
int arr[25];
for (int i = 0; i <= n; i++)
{
arr[i] = 0;
}
arr[1] = 0;
arr[2] = 1;
if (n == 1)
{
return arr[1];
}
else if (n == 2)
{
return arr[2];
}
else
{
for (j = 3; j <= n; j++)
{
arr[j] = arr[j - 1] + arr[j - 2];
cout << arr[j];
}
return arr[j];
}
}
when i am compiling the code its giving garbage value but i dont understand why please if you can try to help , here i am using fibonecci using memorizaion .
here i am taking an arrayarr[] for storing the value as a memory.
The garbage value that you are getting is because of the following reason:
You initialize elements a[0] to a[n] with 0, so elements from a[n+1] and afterwards are uninitialized (and hence might contain garbage value).
When you exit the for loop, the value of j is equal to n+1 and not n. So your function returns the garbage value of a[n+1].
You can easily fix this bug by just returning arr[--j] instead of a[j] after the for loop.
Also, you can now comment off the cout inside the for loop, otherwise it will further spoil your output.

Finding the mode of a sorted array using bin search

Hi there i've been tasked with Writing a simple program that is given an array of integers and determines the mode, which is the number that appears most frequently in the array.
The approach i'm trying to adopt is using a bubble sort with a bin search algorithm my level of knowledge is at a beginner stage can someone help point me?
Where i'm going wrong i believe it to be passing the correct search value to find it in the array! But i maybe wrong but some help would be very much appreciated, thanks in advance for those to take time to try help me.
#include <iostream>
using namespace std;
const int arrayLength = 10;
int searchVal;
int numGroup[arrayLength];
bool isSorted(int [], int arrayLength);
int binSearch(int [],int arrayLegth,int searchVal);
int main()
{
// Take in num
for (int index = 0; index < arrayLength; index++)
{
cout << "Enter Number: ";
cin >> numGroup[index];
}
// Sort numbers
//var to hold the val being swaped
int swapHolder = 0;
//bubble sort
for (int iSort = 0; iSort < arrayLength; iSort++)
{
for (int jSort = (iSort + 1); jSort <= arrayLength - 1; jSort++)
{
if (numGroup[iSort] > numGroup[jSort])
{
swapHolder = numGroup[iSort];
numGroup[iSort] = numGroup[jSort];
numGroup[jSort] = swapHolder;
}
}
}
//passes the sorted array and the length to the isSorted
isSorted(numGroup, arrayLength);
return 0;
}
bool isSorted(int numGroup[], int arrayLength){
cout << "Final result" << endl;
for (int index = 0; index < arrayLength - 1 ; index++)
{
if (numGroup[index] > numGroup[index + 1])
{
cout << "it's false";
system("pause");
return false;
}
cout << numGroup[index] << endl;
//cout << arrayLength << endl;
}
cout << numGroup[arrayLength - 1] << endl;
//trying to make searchVal
for (int i = 0; i < numGroup[arrayLength - 1]; i++)
{
if (numGroup[i] == numGroup[i])
{
int searchVal = numGroup[i];
}
}
binSearch(numGroup, arrayLength, searchVal);
cout << "It's true ";
system("pause");
return true;
}
int binSearch(int numGroup[], int arrayLength,int searchVal){
int low = 0;
int high = arrayLength - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
//search through the array
if (searchVal == numGroup[mid])
{
return mid;
}
else if (searchVal > numGroup[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
cout << "In bin search " << mid;
return mid;
}
You don't need to sort the array. You can have another array (freq) which will count the numbers appearances. So, a mini code for that:
int myArray[10];
int freq[1000]; //we assume that the numbers are smaller than 1000
void count()
{
for(int i = 0; i < 10; ++i)
{
++freq[v[i]];
}
}
int ReturnModeElement()
{
int maxFreq = -1;
int element = -1;
for(int i = 0 ; i < 10; ++i)
{
if(freq[v[i]] > maxFreq)
{
maxFreq = freq[v[i]];
element = v[i];
}
}
return element;
}
I hope you got the idea :)

C++ program wont compile with expected expression and function not allowed here

#include <iostream>
using namespace std;
const int lab8 = 10;
int labArray[lab8];
void promptUser(int [], int);
void sortArray(int [], int);
void showArray(const int[], int);
int searchArray(const int [], int, int value);
int x = 0;
int results = 0;
int main()
{
promptUser(labArray, lab8);
sortArray(labArray, lab8);
showArray(labArray, lab8);
cout << "Choose an integer you want to search from the array: " << endl;
cin >> x;
results = searchArray(labArray, lab8, x);
if (results == -1) {
cout << "That number does not exist in the array. \n";
else
{
cout << "The integer you searched for was for at element " << results;
cout << " in the array. \n";
}
}
void promptUser(int numbers[], int size)
{
int index;
for (index = 0; index <= size - 1;index++ )
{
cout << "Please enter ten numbers to fill the array " << endl
<< (index + 1) << ": ";
cin >> numbers[index];
}
}
void sortArray(int array[], int size)
{
bool swap;
int temp;
do
{
swap = false;
for (int count = 0; count < (size -1); count++)
{
if (array[count] > array[count + 1])
{
temp = array[count];
array[count] = array[count + 1];
array[count + 1] = temp;
swap = true;
}
}
} while (swap);
}
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
{
cout << "The array you entered when sorted was: ";
cout << array[count] << " ";
cout << endl;
}
}
int searchArray(const int array[], int size, int value)
{
int first = 0,
last = size - 1,
middle,
position = - 1;
bool found = false;
while (!found && first <= last)
{
middle = (first + last) / 2;
if (array[middle] == value)
{
found = true;
position = middle;
}
else if (array[middle] > value)
last = middle - 1;
else
first = middle + 1;
}
return position;
}
I am new to c++ and just working on an assignment for my class. I thought the program I wrote would have worked but for the life of me I can not figure out why it will not compile. I am sure I am missing something or not understanding how it should work completely. The errors I keep receiving are expected expression on line 26 by the 'else' statement and when I put the 'if' and 'else' statements in I started receiving function not allowed here errors. Any help would be greatly appreciated.
In the if statement, you open the bracket { but you never close it. Not sure if this is the problem but it should raise some issues.
if (results == -1) {
cout << "That number does not exist in the array. \n";
**}**
else
{
cout << "The integer you searched for was for at element " << results;
cout << " in the array. \n";
}
This is how it should look. Try it

Having problems with binary search c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Im having a problem with a binary search function. It only seems to work when the randomly generated search key is already in the middle position of the array. Ive tried a lot of things but cant seem to figure out why it's doing this.
#include<iostream>
#include<ctime>
using namespace std;
void printarray(int[], int);
void fillarray(int[], int);
void descendingSort(int[], int);
int binarySearch(int[], int, int);
int main()
{
srand((unsigned int)time(0));
bool quit = false;
while (quit == false)
{
int key = rand() % 100 + 1;
const int size = 16;
int mainarray[size] = {};
fillarray(mainarray, size);
printarray(mainarray, size);
descendingSort(mainarray, size);
cout << endl;
cout << "Ordered array after selection sort:" << endl;
printarray(mainarray, size);
cout << endl;
int result = binarySearch(mainarray, size, key);
cout << "Searching for key value " << key << endl;
if (result >= 0)
{
cout << "Key value " << key << " found at position " << result << endl;
}
else
{
cout << "Key value " << key << " not found!" << endl;
}
cout << "Continue (y/n)? :";
char x;
cin >> x;
cout << endl;
if (x == 'y')
quit = false;
if (x == 'n')
quit = true;
}
return 0;
}
void printarray(int array[], int size)
{
for (int i = 0; i < size; i++)
{
cout << array[i] << " ";
}
}
void fillarray(int random[], int size)
{
for (int j = 0; j <= size - 1; j++)
{
random[j] = rand() % 100 + 1;
}
}
void descendingSort(int array[], int size)
{
int max, next;
for (int i = 0; i < size - 1; i++)
{
max = i;
for (int j = i + 1; j < size; j++)
{
if (array[max] < array[j])
max = j;
}
if (max!= i)
{
next = array[i];
array[i] = array[max];
array[max] = next;
}
}
}
int binarySearch(int array[], int size, int key)
{
int low = 0, high = size - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (key == array[mid])
{
return mid;
}
else if (key < array[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
Since you are sorting in descending order, your case is backwards.
See code below where I replaces > with <
if (key == array[mid])
{
return mid;
}
else if (key > array[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
By adding some code above the if it allowed me to visualize what was going wrong.
cout << "Searching in: ";
for (int i = low; i < high + 1; i++)
{
cout << array[i] << " ";
}
cout << endl;