C++ program goes into a never-ending input cycle - c++

This is a simple binary search program, but for some reason, the program just doesn't move on after asking for the value of the key from the user. At first, I thought it is an issue with my compiler, but it still happens wherever I paste the code, and I don't know why.
#include <iostream>
using namespace std;
int binary(int arr[], int n, int k){
int s = 0;
int e = n;
int mid = (s+e)/2;
while(s<=e){
if(k==arr[mid]){
return mid;
}
else if(k>arr[mid]){
s = mid+1;
}
else if(k<arr[mid]){
e = mid-1;
}
}
return -1;
}
int main(){
int i, n, key;
cin>>n;
int a[n];
for(i=0;i<n;i++){
cin>>a[i];
}
cout<<"Enter key:"<<endl;
cin>>key;
cout<< binary(a, n, key);
}
Instead of moving on after k, the code just does nothing.

you code is looping in the 'binary ' function
try this to see
while(s<=e){
cout << s << e; <<<=====
learn to use your debugger to step through the code

The middle element is found inside the loop in binary search because the search interval is reduced to half in every iteration.
Your mid is not changing that is why the program is not terminating.
So final code after correction is:
#include <iostream>
using namespace std;
int binary(int arr[], int n, int k)
{
int s = 0;
int e = n;
while (s <= e)
{
int mid = (s + e) / 2;
if (k == arr[mid])
{
return mid;
}
else if (k > arr[mid])
{
s = mid + 1;
}
else if (k < arr[mid])
{
e = mid - 1;
}
}
return -1;
}
int main()
{
int i, n, key;
cin >> n;
int a[n];
for (i = 0; i < n; i++)
{
cin >> a[i];
}
cout << "Enter key:" << endl;
cin >> key;
cout << binary(a, n, key);
}

Related

Getting error on submission for Kattis "OddGnome" problem. I am getting the right output locally, what is wrong with my code? C++

#include <stdio.h>
int main(){
int n, g, i;
scanf("%d\n", &n);
while(n--) {
int l = -1;
int c = 1;
scanf("%d", &g);
while(g--) {
scanf("%d", &i);
if (l == -1) l = i;
else if (i - 1 != l) break;
else l++;
c++;
}
fflush(stdin);
printf("%d\n", c);
}
}
I get all the outputs correctly, so I have no idea what could be wrong. On the other hand, Kattis accepts this code below that I found on GitHub, and the outputs are exactly the same as in my code. If anyone can explain to me what is wrong or why Kattis rejects my code I would appreciate it.
#include <bits/stdc++.h>
using namespace std;
int main()
{
//Initialize n and g, take in n
int n, g;
cin >> n;
//Iterate n times
while (n--)
{
//Take in g, initialize empty vector of size g
cin >> g;
vector<int> gnomes(g);
//Take in all the gnomes
for (int i = 0; i < g; i++) cin >> gnomes[i];
//Iterate through without the beginning or end since king won't be there
for (int i = 1; i < g-1; i++)
{
//Must break the order, and if you remove it the gnomes around it should be in order
if (gnomes[i] < gnomes[i-1] || gnomes[i] > gnomes[i+1] && gnomes[i-1] < gnomes[i+1])
{
//Output the 1 based index, so add 1
cout << i+1 << endl;
//And exit to the next group
break;
}
}
}
}
First of all, if you're using C++, use C++, not C!
As pointed out, fflush(stdin) is undefined behavior. Instead, you can use std::getline to chew up the rest of the line.
Other than that, your logic looks fine, even though it's a different approach than the overkill C++ solution. There's no need to check i + 1 or use a vector, as you seem to have deduced.
I suggest using clearer naming and whitespace conventions, though.
Here's a C solution, using scanf to read the rest of the line:
#include <stdio.h>
int main() {
int n;
scanf("%d\n", &n);
for (int i = 0; i < n; i++) {
int previous = -1;
int g;
scanf("%d", &g);
for (int j = 0; j < g; j++) {
int current;
scanf("%d", &current);
if (previous >= 0 && previous + 1 != current) {
printf("%d\n", ++j);
for (; j < g; j++) {
scanf("%d", &current);
}
break;
}
previous = current;
}
}
}
Here's a C++ solution that uses bits/stdc++.h and using namespace std;, which are common idioms in competitive programming but should never be used in any application code.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int g;
cin >> g;
int previous = -1;
for (int j = 0; j < g; j++) {
int current;
cin >> current;
if (previous >= 0 && previous + 1 != current) {
cout << (1 + j) << "\n";
string s;
getline(cin, s);
break;
}
previous = current;
}
}
}

To search an element using Binary Search

I tried the following code for searching an element in the array using binary search without using the function, but it does not work as it stops just after asking the Number I am searching for in the array. Not able to figure out, As exactly where I am mistaken.
Using Visual Studio Code.
int main()
{
int arr[10],n,num,mid,l=0,h=n-1,i;
cout<<"Enter the number of elements in the array\n";
cin>>n;
cout<<"Enter the elements of the array\n";
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
cout<<"Enter the number to be searched.\n";
cin>>num;
while(l<=h)
{
mid=(l+h)/2;
if(arr[mid]==num)
{
cout<<"Number found at "<<mid<<"\n";
break;
}
if(arr[mid]>num)
{
h=mid-1;
}
else
{
l=mid+1;
}
}
if(l>h)
{
cout<<"Number not found.\n";
}
return 0;
}
You have initialized h = n-1 before initializing n. Hence, we have Undefined behaviour.
#include <iostream>
using namespace std;
int main()
{
int arr[10], n, num , mid, l, h, i;
cout<<"Enter the number of elements in the array\n";
cin>>n;
cout<<"Enter the elements of the array\n";
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
cout<<"Enter the number to be searched.\n";
cin>>num;
l = 0;
h = n-1;
while(l <= h)
{
mid = (l+h)/2;
if(arr[mid] == num)
{
cout<<"Number found at index "<<mid<<"\n";
break;
}
if(arr[mid] > num)
{
h = mid-1;
}
else
{
l = mid+1;
}
}
if(l > h)
{
cout<<"Number not found.\n";
}
return 0;
}
so here is my code -->
#include <iostream>
#include <cmath>
using namespace std;
int binarySearch(int arr[] , int first , int last ,int value){
if(last >= first){
int mid = first + (last-first)/2;
if(arr[mid] == value){
return mid;
}
if(value > arr[mid]){
return binarySearch(arr , mid+1 , last , value);
}else if(value< arr[mid]){
return binarySearch(arr , first , mid-1 , value);
}
}
return -1;
}
int main(){
int n; cin >> n;
int arr[n];
for(int i=0 ; i<n ; i++){
cin >> arr[i];
} // requires sorted array
int value ; cin >> value;
cout << binarySearch(arr , 0 , n-1 , value);
return 0;
}

binary search segmentation fault in c++

This works fine...the size of the array is just 7.
// item = search item
int bin(int arr[], int item, int startIndex, int endIndex)
{
if(startIndex <= endIndex)
{
int middle = 1 + (endIndex - startIndex) / 2;
if(item == arr[middle]) return middle;
if(item < arr[middle])
return bin(arr, item, startIndex, middle-1);
return bin(arr, item, middle + 1, endIndex);
}
return -1;
}
int main()
{
int sample[] = {1,2,3,4,5,6,7};
cout<< bin(sample,5,0,6) <<endl;
system("pause");
}
But after increasing the size of array and searching 19...it says segmentation fault.
int main()
{
int sample[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22};
// size of array is 22
cout<< bin(sample,19,0,21) <<endl;
system("pause");
}
Why is it like that? Do I have a semantic error?
Your middle calculation is wrong:
int middle = 1 + (endIndex - startIndex) / 2;
should be:
int middle = startIndex + (endIndex - startIndex) / 2;
You can use the following code:
#include <iostream>
using namespace std;
void Binary(int arr[], int n, int key)
{
int s = 0;
int e = n - 1;
while (s <= e) {
int mid = (s + e) / 2;
if (arr[mid] == key) {
cout << "Element Found At Index No. " << mid;
} else if (arr[mid] > key) {
e = mid - 1;
} else {
s = mid + 1;
}
}
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int key;
cout << "Enter element to be searched!";
cin >> key;
Binary(arr, n, key);
return 0;
}

After reading the theory of Merge Sort , I tried to write an implementation of Merge Sort, but its stuck

After reading through the theory of Merge Sort on TopCoder, I tried to write it's implementations, but it's getting weird, and I'm more or less a beginner in programming, especially algorithms. Can somebody assist me?
#include <iostream>
using namespace std;
int arr[] = {2, 0, 43, 12, 98};
int sizeOfarr(int a[])
{
return sizeof(a)/sizeof(a[0]);
}
int minElement(int x, int y)
{
if (x > y)
{
return y;
}
else if (x < y)
{
return x;
}
else
{
return x, y;
}
}
int main()
{
int t, z;
int n = sizeOfarr(arr);
int finalList[n];
int list1[n];
int list2[n];
for(int i = 0; i<=((n/2)-1); i++)
{
list1[i] = arr[i];
}
for(int j = n/2; j<n; j++)
{
for(int k = 0; k<=((n/2)-1); k++ )
{
list2[k] = arr[j];
}
}
for(int y = 0; y<=n; y++)
{
while(sizeOfarr(finalList)!=n)
{
t = list1[0];
z = list2[0];
finalList[y] = minElement(t, z);
if(finalList[y]==t)
{
list1[0] = list1[1];
}
else if(finalList[y]==z)
{
list2[0] = list2[1];
}
else
{
list1[0] = list1[1];
list2[0] = list2[1];
}
}
}
cout << "The sorted list is: " << finalList << endl;
return 0;
}
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
int temp[10000];
void merge(int *A,int low,int mid,int high)
{
int i=low;
int j=mid+1;
int k=low;
int l;
while(i<=mid && j<=high)
{
if(A[i]<A[j])
{
temp[k]=A[i];
i=i+1;
}
else
{
temp[k]=A[j];
j=j+1;
}
k++;
}
for(l=i;l<=mid;l++,k++)
{
temp[k]=A[l];
}
for(l=j;l<=high;l++,k++)
{
temp[k]=A[l];
}
memcpy(A,temp,sizeof(A[0])*k);
}
void mergeSort(int *A,int low,int high)
{
int mid;
if(low<high)
{
mid=floor((low+high)/2);
mergeSort(A,low,mid);
mergeSort(A,mid+1,high);
merge(A,low,mid,high);
}
}
int main(int argc,char *argv[])
{
int n;
int array[10000];
cout<<"please enter the number numbers\n";
cin>>n;
cout<<"please enter the nubers\n";
for(int i=0;i<n;i++)
{
cin>>array[i];
}
mergeSort(array,0,n-1);
for(int i=0;i<n;i++)
{
cout<<array[i]<<" ";
}
cout<<"\n";
}
This is my implementation
mergeSort function divide recursively at middle and repeats until low lt(less than) high then a merge function is called.
I see from your code that the operator "," (return x,y) would replace x value by y value.
A few comments on the code:
return x,y // this just returns y. this is the case when x==y so it probably is OK bit not what one would write.
while(sizeOfarr(finalList)!=n) // The size of your array finalist is n elements. This is never going to change so this while condition is always false and the loop will never execute.

Quicksort algorithm with duplicate keys

I am trying to implement Quick Sort algorithm. Following code works for unique elements but it doesn't working for arrays having duplicate elements. Please tell me where I am doing wrong. Also when I change value of pivot to some other number other than 0 , program crashes. Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
void swapme(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
// these two variables will take care of position of comparison
int lower = 0, upper = size - 1;
int pivot = 0; // assigns pivot
if (size <= 1)
return;
while (lower < upper)
{
while (arr[lower] < arr[pivot])
{
++lower;
}
}
while (arr[upper] > arr[pivot])
{
--upper;
}
if (upper > lower)
{
swapme(arr[upper], arr[lower]);
// upper--;
// lower++;
}
quicksort(arr, lower);
quicksort(&arr[lower + 1], size - 1 - lower);
}
int main()
{
int arr[30];
for(int j = 0; j < 30; j++)
{
arr[j] = 1 + rand() % 5000;
}
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
quicksort(arr, 30);
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
cin.get();
cin.get();
}
Update: I have finally managed to make it work. Here is the fixed version:
void swapme(int &a, int &b )
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
if (size <= 1)
return;
// These two variables will take care of position of comparison.
int lower = 0;
int upper = size-1;
int pivot = arr[upper/2]; // assigns pivot
while (lower <= upper)
{
while (arr[lower] < pivot)
++lower;
while (arr[upper] > pivot)
--upper;
if (upper >= lower)
{
swapme(arr[upper],arr[lower]);
if(arr[upper] == arr[lower])
{
// Can either increment or decrement in case of duplicate entry
upper--; // lower++;
}
}
}
quicksort(arr, lower);
quicksort( &arr[lower+1], size-1-lower);
}
You are storing the index of your pivot element in the pivot variable, so swapping the elements can potentially change the choice of pivot element during the loop. Not a very good idea. I would suggest storing the actual value of the pivot element inside pivot instead.
Also, if this really isn't homework, why don't you simply use the standard library facilities?
#include <algorithm>
// ...
std::sort(arr + 0, arr + 30);
You will get heavily optimized and tested code that will outperform your handwritten Quicksort anytime.
Quick Sort that can implement any number of i/p integers. it also deal with duplicate keys
#include <conio.h>
#include <string>
using namespace std;
void InputArray(int*,int);
void QuickSort(int *,int,int);
int partition(int *,int,int);
void swap(int *,int,int);
void printArr(int *,int Siz=11);
void main(){
int siz;
cout<<"Enter Array length : "; cin>>siz;
int *a=new int[siz];
InputArray(a,siz);
QuickSort(a,0,siz-1);
int i=0,j=11;
printArr(a,siz);
system("pause");
}
void InputArray(int*a,int s){
for(int i=0; i<s; i++){
cout<<"ELement ["<<i<<"] = "; cin>>a[i];
}
}
void QuickSort(int *a,int start,int end){
if(start<end){
int pivot=partition(a,start,end);
QuickSort(a,start,pivot);
QuickSort(a,pivot+1,end);
}
}
int partition(int *a,int start,int end){
int currentPivotValue=a[start];
int i=start-1, j=end+1;
while(true){
i++;
while(i<j && a[i]<currentPivotValue){ i++; }
j--;
while(j>start && a[j]>currentPivotValue) {j--;}
if(i<j) swap(a,i,j);
else return j;
}
}
void swap(int *b,int i,int j){
int t=b[i];
b[i]=b[j];
b[j]=t;
}
void printArr(int *a,int Siz){
for(int i=0; i<Siz; i++) cout<<a[i]<<" ";
}