Finding minimum and maximum in a array c++ - c++

I have to find the minimum and maximum value of elements in a array using divide and conquer. I have written a code but it is not working for more then 6 elements in array. I don't know whats the problem
#include<iostream>
using namespace std;
int minimum=999,maximum,mi,ma;
void result(int mi,int ma)
{
if(maximum<ma)
{
maximum=ma;
}
if(minimum>mi)
{
minimum=mi;
}
}
void maxmin(int arr[],int i,int j)
{
cout<<" i ="<<i<<" j= "<<j<<endl;
if(i==j)
{
mi=ma=arr[i];
result(mi,ma);
}
else if(i==j-1)
{
if(arr[i]>arr[j])
{
ma=arr[i];
mi=arr[j];
}
else
{
mi=arr[i];
ma=arr[j];
}
result(mi,ma);
}
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
}
int main()
{
int arr[10],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
maxmin(arr,0,n-1);
cout<<" max "<<maximum<<" min "<<minimum<<endl;
return 0;
}

Your code has a few mistakes
Your code reads n from the user input, but you provided only 10 sized array, and user can try to input 10+ numbers, so we will have an undefined behavior in that case.
You write it very bad and unreadable. If you want somebody else to read your code, check in the your favourite book or in the internet information about how to write beautiful and readable code.
You implemented that algorithm yourself. It is a bad habit, use the standard library algorithms and you will not encounter such mistake.
.
#include <iostream> // std::cin, std::cout
#include <cstddef> // std::size_t
#include <algorithm> // std::min_element, std::max_element
int main ()
{
std::size_t array_size;
std::cin >> array_size;
int *some_array = new int[array_size]; // Allocate memory dynamically
for(std::size_t i = 0; i < array_size; ++i)
{
std::cin >> some_array[i];
}
/* Standard library operate on iterators, they are special classes
* that have interface that is similar in many cases to pointers (so we can use pointers as iterators).
* std::min/max_element needs one iterator for the sequence beginning
* and one iterator after the end. It returns iterator to a found element.
*/
int min = *std::min_element(some_array, some_array + array_size);
int max = *std::max_element(some_array, some_array + array_size);
delete[] some_array;
std::cout << "Min = " << min << std::endl << "Max = " << max;
std::cout << std::endl;
}

Code isn't well written and first dry run your code, you will find the problem easily.
Change
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
To
else
{
int mid=(i+j)/2; /*** Adding brackets ***/
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
And check the logic for calling the result function (because according to your logic the two subsets are individually calculating MIN and MAX in itself not in whole array)

Related

Can we pass an array to any function in C++?

I have passed an array of size 10 to a funtion to sort the array reversely, but it's going wrong after rightly sorting first five elements of the array.
I want to sort the array 'std' reversely here,
# include <iostream>
using namespace std;
int reverse(int a[]); //funtion prototype
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
}
int reverse(int a[]) //funtion defination
{
int index = 0;
for (int i = 9; i >= 0; i--)
{
a[index] = a[i]; //swaping values of the array
cout << a[index] << " ";
index++;
}
}
There's basically three things wrong with your code.
You aren't swapping anything
You have to swap the first half of the array with the second half, not swap the whole array. If you do that then everything gets swapped twice, so that nothing changes
You should print the reversed array after you have finished the reverse, not while you are doing the reverse.
Here's some code that fixes all these problems
# include <iostream>
# include <utility>
void reverse(int a[]);
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
// print the array after reversing it
for (int i = 0; i < 10; ++i)
std::cout << std[i] << ' ';
std::cout << '\n';
}
void reverse(int a[])
{
for (int i = 0; i < 5; ++i) // swap the first half of the array with the second half
{
std::swap(a[i], a[9 - i]); // real swap
}
}
Yes you can.
I usually don't use "C" style arrays anymore (they can still be useful, but the don't behave like objects). When passing "C" style arrays to functions you kind of always have to manuall pass the size of the array as well (or make assumptions). Those can lead to bugs. (not to mention pointer decay)
Here is an example :
#include <array>
#include <iostream>
// using namespace std; NO unlearn trhis
template<std::size_t N>
void reverse(std::array<int, N>& values)
{
int index = 0;
// you only should run until the middle of the array (size/2)
// or you start swapping back values.
for (int i = values.size() / 2; i >= 0; i--, index++)
{
// for swapping objects/values C++ has std::swap
// using functions like this shows WHAT you are doing by giving it a name
std::swap(values[index], values[i]);
}
}
int main()
{
std::array<int,10> values{ 0,1,2,3,4,5,6,7,8,9 };
reverse(values);
for (const int value : values)
{
std::cout << value << " ";
}
return 0;
}

How can I print the numbers in main function?

I am new to c++ language. I am trying to solve a problem using function. I have to print the pentagon numbers untill the integer input, but when function returns the values, it only prints one value. I would love some help with it.
#include<iostream>
using namespace std;
int pent(int num){
int p;
for(int i=1;i<=num;i++){
p=(i*(3*i-1)/2);
}
return p;
}
int main(){
int num;
cin>>num;
int sender=pent(num);
cout<<sender<<endl;
return 0;
}
Your function returns int, that is a single integer. To return more, you can use std::vector. As you probably are not familiar with it, I will give you some pointers...
The most simple constructor creates a vector with no entries:
std::vector<int> x;
You can reserve space for elements via reserve:
x.reserve(num);
The vector still has no elements, but it already allocated enough space to hold num elements. This is important, because when we will add elements the vector will grow and that potentially requires to copy all elements to a different place in memory. We can avoid such frequent reallocations by reserving enough space upfront.
To add elements to the vector you can use push_back:
x.push_back(42);
Eventually to print all elements of the vector we can use a range-based for loop:
for (auto element : x) std::cout << element << " ";
So you can rewrite your code like this:
#include <iostream>
#include <vector>
std::vector<int> pent(int num){
std::vector<int> result;
result.reserve(num);
for(int i=1;i<=num;i++){
result.push_back(i*(3*i-1)/2);
}
return result;
}
int main(){
int num;
std::cin >> num;
auto sender = pent(num);
for (auto number : sender) std::cout << number << " ";
}
In your program, from your pent() function you are only returning last calculated value. In you ever time, you are overwriting you variable p.
So there is a way which #asmmo is suggesting, to print in pent() function.
Or you can pass a vector to your pent() function and store values in that and print it in main function.
For your ref:
void pent(int num, vector<int> &arr) {
int p;
for (int i = 1; i <= num; i++) {
arr[i-1] = (i*(3 * i - 1) / 2);
}
}
int main() {
int num;
cin >> num;
vector<int> arr(num);
pent(num, arr);
for (int i = 0; i < num; i++) {
cout << arr[i] << endl;
}
return 0;
}

sieve upto 2 billion gives segmentation fault

I am using this program to check a number if prime or not.
Use algorithm - Sieve :
#include<bits/stdc++.h>
//#define _max 2000000001
#define _max 20000001
using namespace std;
bool sieve[_max];
void init()
{
memset(sieve,true,sizeof(sieve));
sieve[0]=sieve[1]=false;
for(int i=2;i<_max;i+=2)
{
sieve[i]=false;
}
}
void go_sieve(int n)
{
n++;
for(int i=3;i<n;i+=2)
{
if(sieve[i]==false)
continue;
for(int j=2*i;j<n;j+=i)
sieve[j]=false;
}
}
void print(int n)
{
n++;
printf("-------------\n");
for(int i=0;i<n;i++)
{
if(sieve[i])
cout << i << " ";
}
printf("\n-------------\n");
}
int main()
{
init();
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
go_sieve(x);
//print(x);
if(sieve[x])
printf("Prime\n");
else
printf("Not prime\n");
}
return 0;
}
Now it works upto 2e7 and pretty smoothly, but I want to check upto 2e9, if I change my _max to 2000000001 it gives me segmentation error and exits with an error code.
How can I resolve this problem ?
I have tried a new approach with set :
#include<bits/stdc++.h>
//#define _max 200001
//#define _max 20000001
#define _max 2000000001
using namespace std;
set<int>prime;
set<int>nprime;
void init()
{
prime.insert(2);
}
void go_sieve()
{
for(int i=3;i<_max;i+=2)
{
if(prime.find(i)==prime.end() && nprime.find(i)==nprime.end())
{
prime.insert(i);
//cout << i << endl;
for(int j=2*i;j<_max;j+=i)
nprime.insert(j);
}
if(nprime.find(i)!=nprime.end())
nprime.erase(nprime.find(i));
}
}
void print()
{
set<int> ::iterator itt;
printf("-------------\n");
for(itt=prime.begin();itt!=prime.end();itt++)
{
cout << *itt << " ";
}
printf("\n-------------\n");
}
int main()
{
init();
go_sieve();
//print();
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
if(prime.find(x)!=prime.end())
printf("Prime\n");
else
printf("Not prime\n");
}
return 0;
}
Target is to execute it within 512MB~1GB memory.
If you want to enumerate large ranges of prime numbers, you should use a segmented Sieve of Eratosthenes; it will be faster (due to caching effects) and use less memory.
If you only want to determine if one number is prime, or a few numbers, sieving is a horrible way to do it. Sieving should only be used when you are interested in an entire range of numbers. For n up to a billion, trial division is simple and probably fast enough. For larger numbers, a Miller-Rabin test or Baillie-Wagstaff test is probably better.
I can't reproduce this on my system. My guess is that this has to do with a system dependant limitation.
You declare sieve as a global array (static storage duration) and it's huge (i.e. 2000000001 * sizeof(bool) - could be 2-8G depending on sizeof bool). Maybe your system can't handle that.
Instead of a global array, try using dynamic allocation:
// bool sieve[_max]; comment out this
bool* sieve = NULL;
...
...
int main()
{
sieve = (bool*)malloc(_max * sizeof *sieve);
if (sieve == NULL)
{
// out of memory
exit(1);
}
...
That said:
Your code is C++ but your style is more C like.
In C++ you would probably use a std::vector instead. That would make everything much easier.
BTW: Also avoid globals. Instead define the vector (or dynamic array) in main and pass it by-reference to the functions.
You probably hit some memory limit on your system which causes the segmentation fault.
However, you don't need such a big array. Using Sieve of Eratosthenes, you need to calculate numbers up to x. Instead of an array you can use std::vector and increase its size as you calculate more numbers. This should allow you to calculate some numbers, but with large numbers you will hit the memory limit again.
You could also use some algorithm which requires you to store fewer numbers. To determine whether x is prime, you only need to compare against prime numbers that are smaller than the square root of x. You don't have to store numbers that are not primes. With x = 1e10, you would only need to store 5e8 numbers.
Here is some example with vector (probably not optimal):
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
std::vector<int> primes = {2};
void calculate(int x) {
const int largest_prime = primes.back();
if (largest_prime >= x) {
// Already calculated
return;
}
for (size_t i = largest_prime + 1; i <= x; i++) {
bool not_prime = false;
for (size_t j = 0; j < primes.size(); j++) {
if (i % primes[j] == 0) {
not_prime = true;
break;
}
}
if (!not_prime) {
primes.push_back(i);
}
}
}
bool check(int x) {
calculate(x);
return std::find(primes.begin(), primes.end(), x) != primes.end();
}
int main() {
std::cout << check(15) << std::endl;
std::cout << check(256699) << std::endl;
}

Deleting element from an array in c++

I have read others posts, but they don't answer my problem fully.
I'm learning to delete elements from an array from the book and try to apply that code.
As far as I can grasp I'm passing array wrong or it is sending integer by address(didn't know the meaning behind that).
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(double x[], int& n, int k);
int main()
{
// example of a function
int mass[10]={1,2,3,45,12,87,100,101,999,999};
int len = 10;
for(int i=0;i<10;i++)
{
cout<<mass[i]<<" ";
};
delete_element(mass[10],10&,4);
for(int i=0;i<10;i++)
cout<<mass[i]<<" ";
return 0;
}
void delete_element(double x[], int& n, int k)
{
if(k<1 || k>n)
{
cout<<"Wrong index of k "<<k<<endl;
exit(1); // end program
}
for(int i = k-1;i<n-1;i++)
x[i]=x[i+1];
n--;
}
There are a couple of errors in your code. I highlight some of the major issues in question 1-3:
You call exit, which does not provide proper cleanup of any objects since it's inherited from C. This isn't such a big deal in this program but it will become one.
One proper way too handle such an error is by throwing an exception cout<<"Wrong index of k "<< k <<endl;
exit(1);
Should be something like this:
throw std::runtime_error("invalid index");
and should be handled somewhere else.
You declare function parameters as taking a int& but you call the function like this: delete_element(mass[10],10&,4); 10& is passing the address of 10. Simply pass the value 10 instead.
You are "deleting" a function from a raw C array. This inherently doesn't make sense. You can't actually delete part of such an array. It is of constant compile time size created on the stack. The function itself doesn't do any deleting, try to name the functions something more task-oriented.
You are using C-Arrays. Don't do this unless you have a very good reason. Use std::array or std::vector. These containers know their own size, and vector manages it's own memory and can be re sized with minimal effort. With containers you also have access to the full scope of the STL because of their iterator support.
I suggest you rewrite the code, implementing some type of STL container
Line 15: syntax error
you can't pass a number&
If you want to pass by reference, you need to create a variable first, like:
your delete_element function signature conflicts with your declared arrays. Either use a double array or int array and make sure the signatures match.
delete_element(mass, len , 4);
when you write the name of an array without the brackets, then it's the same as &mass[0]
ie. pointer to the first element.
complete changes should be:
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main(){
// example of a function
int mass[10] = { 1, 2, 3, 45, 12, 87, 100, 101, 999, 999 };
int len = 10;
for (int i = 0; i<10; i++){ cout << mass[i] << " "; };
cout << endl;
delete_element(mass, len , 4);
for (int i = 0; i<10; i++)cout << mass[i] << " ";
cout << endl;
cin.ignore();
return 0;
}
void delete_element(int x[], int& n, int k){
if (k<1 || k>n){
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1; i<n - 1; i++)
x[i] = x[i + 1];
n--;
}
There are a couple of mistakes in your program.
Apart from some syntax issues you are trying to pass an int array to a function which wants a double array.
You cannot pass a lvalue reference of a int literal. What you want is to pass a reference to the length of the int array. see also http://en.cppreference.com/w/cpp/language/reference.
Here is an updated version of your program.
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main() {
// example of a function
int mass[10] = { 1,2,3,45,12,87,100,101,999,999 };
int len = 10;
for (int i = 0;i < len;i++)
cout << mass[i] << " "; ;
cout << endl;
delete_element(mass, len, 4);
for (int i = 0;i < len;i++) // len is 9 now
cout << mass[i] << " ";
cout << endl;
return 0;
}
void delete_element(int x[], int& n, int k) {
if (k<1 || k>n) {
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1;i<n - 1;i++)
x[i] = x[i + 1];
n--;
}
Although it does not answer your question directly, I would like to show you how you can use C++ to solve your problem in a simpler way.
#include <vector>
#include <iostream>
void delete_element(std::vector<int>& v, const unsigned i)
{
if (i < v.size())
v.erase(v.begin() + i);
else
std::cout << "Index " << i << " out of bounds" << std::endl;
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7};
delete_element(v, 4);
for (int i : v)
std::cout << i << std::endl;
return 0;
}
You cannot delete elements from an array, since an array's size is fixed. Given this, the implementation of delete_element can be done with just a single call to the appropriate algorithm function std::copy.
In addition, I highly suggest you make the element to delete a 0-based value, and not 1-based.
Another note: don't call exit() in the middle of a function call.
#include <algorithm>
//...
void delete_element(int x[], int& n, int k)
{
if (k < 0 || k > n-1 )
{
cout << "Wrong index of k " << k << endl;
return;
}
std::copy(x + k + 1, x + n, x + k);
n--;
}
Live Example removing first element
The std::copy call moves the elements from the source range (defined by the element after k and the last item (denoted by n)) to the destination range (the element at k). Since the destination is not within the source range, the std::copy call works correctly.

Code failure insert digits before data of the vector

I am supossed to do a code using function which after asking the user for input,puts number before the vector like this:
if vector is 11,12,13,14
new vector is 1 11 2 12 3 13 4 14 until the vector finishes and then I have to print it but I get an error of vector subscript out of range,aprecciate any help.
Here is my code
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<double> llena_vector(int x,vector<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x);
ingreso.push_back(x);
return ingreso;
}
vector<double> arma_vector(int contador,vector<double> intercalado)
{
int i=0;
for(contador=1;contador< intercalado.size()+1;contador++);{
intercalado.insert(intercalado.begin()+i,contador);i++;}
return intercalado;
}
vector<double> imprime_vector(int cuenta,vector<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++);
cout<<imprimir[cuenta]<<" ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
vector<double> usuario;
vector<double> guardar;
vector<double> resultado;
vector<double> print;
guardar= llena_vector(y,usuario);
resultado=arma_vector(q,guardar);
print=imprime_vector(w,resultado);
system("pause");
}
Here is a cleaner version of the code, in working condition.
#include <iostream>
#include <vector>
using namespace std;
void fill_vector(vector<double>& v)
{
cout << "Enter 5 numbers." << endl;
for (int i = 0; i < 5; ++i)
{
double d;
cin >> d;
v.push_back(d);
}
}
void insert_count(vector<double>& v)
{
size_t size = v.size();
for (size_t i = 0, j = 0; i < size; ++i, j += 2)
{
vector<double>::iterator pos = v.begin() + j;
v.insert(pos, i + 1);
}
}
void print_vector(vector<double>& v)
{
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;
}
int main()
{
vector<double> v;
fill_vector(v);
insert_count(v);
print_vector(v);
}
Like others (may have) pointed out:
you didn't need to pass by value (you're basically passing around a bunch of copies), you can pass by reference instead to reduce overhead and speed it up
you shouldn't put semicolons (;) directly behind your loop statements
size_t is often better than int when looping on size
you included <string> when it wasn't being used
you were passing arguments that weren't needed (e.g. a counter)
you used a while loop for user input, but it's only appropriate when piping in data otherwise it will loop forever; a for loop with a known count is more appropriate for user input
the function that inserted numbers between the existing elements had an error, you were incorrectly calculating the position to insert
your code formatting was a mess, making the code very difficult to read
you shouldn't pollute the namespace (i.e. using namespace std), but I left it as is since it's common in example code
if you're using C++11, I recommend using a for-each loop for printing the vector, and the auto keyword when declaring the iterator
i guess there is a typo: you should remove the last ; in for(cuenta=0;cuenta<imprimir.size();cuenta++);
Edit: as pointed by jrd1, you have this typo in all your for and while loops...
To begin with, your code has a number of issues. But, I've modified it to keep it as similar to your original.
#include <iostream>
#include <string>
#include <deque>
#include <cstdlib>
using namespace std;
deque<double> llena_deque(int x, deque<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x)
ingreso.push_back(x);
return ingreso;
}
deque<double> arma_deque(int contador, deque<double> intercalado)
{
int size = intercalado.size()+1;
for(int i=1; i < size; ++i) {
cout << i << endl;
intercalado.push_front(i);
}
return intercalado;
}
deque<double> imprime_deque(int cuenta, deque<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++)
cout << imprimir[cuenta] << " ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
deque<double> usuario;
deque<double> guardar;
deque<double> resultado;
deque<double> print;
guardar= llena_deque(y,usuario);
resultado=arma_deque(q,guardar);
print=imprime_deque(w,resultado);
return 0;
}
All your loops had ; at the end of them. That's one reason why you're getting your errors, as the semi-colon terminates a statement - hence, your loops were never truly accessing the vectors, which is why you were getting the memory access violations.
You're passing all your memory by value (which could potentially be slow). Consider using references.
Your operations suggest that you constantly need to keep pushing new data in front of your vector. If so, then use deque (as I did) as it is has functionality designed explicitly for that purpose (insert operations at both ends).
Although, I will say that the logic of your code is quite puzzling at times: i.e. in arma_vector, why pass the value of contador if you don't even use it? You could have used i instead...