Why does the following code throw std::bad_alloc? - c++

I have written code to test how many of the same numbers are present in both arrays, but for some reason it throws 'std::bad_alloc' could anyone explain why? It only throws it when N = 1000000 for some reason, is it because I have allocated 4000000 bytes of memory?
Here's the code:
#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <algorithm>
#include <math.h>
#include <iomanip>
using namespace std;
int find_last_before_zero(const vector<int>& vec) {
for (int i = vec.size() - 1; i >= 0; --i) {
if (vec[i] != 0) return i + 1;
}
return vec.size();
}
void gen_random_array(vector<int>& vec){
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist(100000, 100200);
for(int i = 0; i < vec.size(); ++i){
vec[i] = dist(gen);
}
}
void binSearchClient(int T){
int counters[4] = {0,0,0,0};
string names[4] = {"for n = 1000 = ", "for n = 10000 = ", "for n = 100000 = ", "for n = 1000000 = "};
for(int i = 0; i < T; ++i){
int N = 1000;
for(int k = 0; k < 4; ++k){
N *= pow(10.0, k);
vector<int> first(N), second(N);
gen_random_array(first, N); gen_random_array(second, N);
vector<int> intersection(N);
sort(first.begin(), first.end()); sort(second.begin(), second.end());
set_intersection(first.begin(), first.end(), second.begin(), second.end(), intersection.begin());
counters[k] += find_last_before_zero(intersection);
}
}
}
}
for(int i = 0; i < 4; ++i){
cout << names[i] << setprecision(10) << std::fixed << (1.0 * counters[i]) / T << endl;
}
}
int main(){
binSearchClient(1);
}

In you first iteration you have N as 1000. Then in for(int k = 0; k < 4; ++k) you do N *= pow(10.0, k);. So for the first iteration N = 1000 (N(1000) * 10^0) The k becomes 1 and you N = 10000 (N(1000) * 10^1). Then k becomes 2 and N = 1,000,000 (N(10000) * 10^2). At k = 3 you get N = 1,000,000,000,000,000 (N(1,000,000) * 10^3) which is more than likely memory than you can allocate.

Related

Debugging a Sums of Digit Factorials

I would to solve this problem illustrated in this image using C++
Define f(n) as the sum of the factorials of the digits of n. For example, f(342) = 3! + 4! + 2! = 32.
Define sf(n) as the sum of the digits of f(n). So sf(342) = 3 + 2 = 5.
Define g(i) to be the smallest positive integer n such that sf(n) = i. Though sf(342) is 5, sf(25) is also 5, and it can be verified that g(5) is 25.
Define sg(i) as the sum of the digits of g(i). So sg(5) = 2 + 5 = 7.
Further, it can be verified that g(20) is 267 and ∑ sg(i) for 1 ≤ i ≤ 20 is 156.
What is ∑ sg(i) for 1 ≤ i ≤ 150?
Image:
Here is my approach. My code takes long time running, and it works
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int factorial(int n);
std::vector<int> int_to_vector(int n);
int sum_vector(std::vector<int> v);
int get_smallest_number(std::vector<int> v, int sum, int n);
int sum_sg(int n )
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int q;
int m,n;
int g;
int sum = 0;
std::vector<int> vec;
cin>>q;
if( 1<=q && q<=100000){
std::vector<int> s;
int fact = 0;
int sg = 0;
for ( int i = 0; i < q; i++){
cin>>n>>m;
fact = factorial(n);
s = int_to_vector(fact);
sum = sum_vector(s);
g = get_smallest_number(s, sum, n);
s = int_to_vector(g);
sum = sum_vector(s);
}
}
return 0;
}
int factorial(int n){
if (n==0) return 1;
return factorial(n-1)*n;
}
std::vector<int> int_to_vector(int n){
std::vector<int> numbers;
while(n>0)
{
numbers.push_back(n%10);
n/=10;
}
return numbers;
}
int sum_vector(std::vector<int> v){
int sum=0;
for(int i = 0; i < v.size(); i++){
sum+=v.at(i);
}
return sum;
}
int get_smallest_number(std::vector<int> v, int sum, int n){
int i = 0;
int factoriel = 1;
std::vector<int> vect;
int sum2 = 0;
while( i < n){
factoriel = factorial(i);
vect = int_to_vector(factoriel);
sum2 = sum_vector(vect);
if( sum2 == sum) return i;
i++ ;
}
return n;
}
I think on recursive solutions, but it seems somehow more complex to implement. Are there any solutions using modern C++ and STL?
Here is below a bad solution with less complexity, please any suggestion to have good and fast code rather than this below,
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
std::vector<int> factorial {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
std::vector<int> int_to_vector(int n);
int sum_vector(std::vector<int> v);
int find_g(int i);
int calculat_sum_fact(std::vector<int> v);
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m,n,q;
std::vector<int> vec;
std::vector<int> s;
std::vector<int> numbers;
cin>>q;
for (int i = 0; i < q; i++){
cin>>n>>m;
numbers.push_back(n);
// cout<< numbers.at(i);
}
for(int k = 0; k < numbers.size(); k++){
int sum = 0;
for (int i = 0; i < numbers.at(k)+1; i++){
s = int_to_vector(find_g(i));
sum += sum_vector(s);
}
cout << sum << "\n";
}
return 0;
}
std::vector<int> int_to_vector(int n){
std::vector<int> numbers;
while(n>0)
{
numbers.push_back(n%10);
n/=10;
}
return numbers;
}
int sum_vector(std::vector<int> v){
int sum=0;
for(int i = 0; i < v.size(); i++){
sum+=v.at(i);
}
return sum;
}
int find_g(int i){
std::vector<int> s ;
int sum = 0;
int j = 0;
//cout<<"sf 1= " << j << endl;
while(true){
s = int_to_vector(j);
sum = calculat_sum_fact(s);
s= int_to_vector(sum);
sum = sum_vector(s);
//cout<<"sf 2= " << j << endl;
if (sum == i) {
//cout<<"sf = " << j << endl;
return j;
//break;
}
//cout<<"sf = " << j << endl;
j++;
}
}
int calculat_sum_fact(std::vector<int> v){
int sum = 0;
for(int i = 0; i < v.size(); i++ ){
sum += factorial.at(v.at(i));
}
return sum;
}

Function to find the smallest prime x and the biggest m = power_of(x) such that n % m = 0 and n % x = 0?

Given m integer from 1 to m, for each 1 <=i <= m find the smallest prime x that i % x = 0 and the biggest number y which is a power of x such that i % y = 0
My main approach is :
I use Eratos agorithm to find x for every single m like this :
I use set for more convenient track
#include<bits/stdc++.h>
using namespace std;
set<int> s;
void Eratos() {
while(!s.empty()) {
int prime = *s.begin();
s.erase(prime);
X[prime] = prime;
for(int j = prime * 2; j <= L ; j++) {
if(s.count(j)) {
int P = j / prime;
if( P % prime == 0) Y[j] = Y[P]*prime;
else Y[j] = prime;
}
}
}
signed main() {
for(int i = 2; i<= m; i++) s.insert(i);
Eratos();
for(int i = 1; i <= m; i++) cout << X[m] << " " << Y[m] ;
}
with X[m] is the number x corresponding to m and same as Y[m]
But it seems not really quick and optimal solution. And the memory request for this is so big and when m is 1000000. I get MLE. So is there an function that can help to solve this problem please. Thank you so much.
Instead of simply marking a number prime/not-prime in the original Sieve of Eratosthenes, save the corresponding smallest prime factor which divides that number.
Once that's done, the biggest power of the smallest prime of a number would mean to simply check how many times that smallest prime appears in the prime factorization of that number which is what the nested for loop does in the following code:
#include <iostream>
#include <vector>
using namespace std;
void SoE(vector<int>& sieve)
{
for (int i = 2; i < sieve.size(); i += 2)
sieve[i] = 2;
for (int i = 3; i < sieve.size(); i += 2)
if (sieve[i] == 0)
for (int j = i; j < sieve.size(); j += i)
if(sieve[j] == 0)
sieve[j] = i;
}
int main()
{
int m;
cin >> m;
vector<int> sieve(m + 1, 0);
SoE(sieve);
for (int i = 2; i < sieve.size(); ++i)
{
int x, y;
x = y = sieve[i];
for (int j = i; sieve[j / x] == x; j /= x)
y *= x;
cout << x << ' ' << y << endl;
}
}
I didn't get what you're trying to do but I understand that you're trying to use Sieve of Eratosthenes to find prime numbers. Well, what you probably need is a bitset, it's like a boolean array but uses bits instead of bytes which means it uses less memory. Here's what I did:
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
vector<int> primes;
int main()
{
const int m = 1e7;
bitset<m> bs;
int limit = (int) sqrt (m);
for (int i = 2; i < limit; i++) {
if (!bs[i]) {
for (int j = i * i; j < m; j += i)
bs[j] = 1;
}
}
for (int i = 2; i < m; i++) {
if (!bs[i]) {
primes.push_back (i);
}
}
return 0;
}

check duplicate numbers with bool function in matrix c++

I created a matrix[10][10] with random numbers
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
matrix[i][j] = rand() % 100 ;
}
}
But I need to use bool function for check duplicate numbers and if its same use random again.How can i do it?
An efficient way to test for duplicates is to store the elements that have been inserted into the matrix in a std::vector and to use to std::find. This allows to check whether a newly generated random number is already included in the previously stored elements or not. If it is found, then another random number should be generated and the test repeated.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
bool alreadySelected(int n, int nvalues, int values[][10]) {
std::vector<int> v(&values[0][0], &values[0][0] + nvalues );
return (std::find(v.begin(), v.end(), n) != v.end());
}
int main() {
int matrix[10][10];
for (int i = 0; i < 10; i++) {
int n;
bool dupe;
for (int j = 0; j < 10; j++) {
int nvalues = i * 10 + j;
do {
n = std::rand() % 100 ;
dupe = alreadySelected( n, nvalues, matrix );
} while ( dupe );
matrix[i][j] = n;
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}
}
A much simpler way to generate such a matrix would be to use std::random_shuffle.
There are multiple ways to achieve this.
Write a function which returns bool and takes 10*10 matrix size. Compute sum of all numbers. Compare this result with the sum of numbers from 1...99. If both matches then no duplicate return true, otherwise duplicate return false. Sum of 1..99 can be calculated using n(n+1)/2, where n = 99.
In function create array of size 100. Initialize all array elements with 0. Iterate over matrix, use matrix element as index of array. If array contains 1 at that position you got duplicate element otherwise make array element at that index 0.
Implementation of first approach
#include <iostream>
#include <cstdlib>
#include <iomanip>
#define ROW 10
#define COL 10
#define MOD 100
int main()
{
int mat[ROW][COL];
int sum = 0;
int range_sum = ((MOD-1)*(MOD))/2; // n = MOD-1, sum = n(n+1)/2
while(true){
sum = 0;
for(int i = 0; i < ROW; i++){
for(int j = 0; j < COL; j++){
mat[i][j] = rand()%MOD;
sum += mat[i][j];
}
}
if(sum==range_sum){
break;
}
}
for(int i = 0; i < ROW; i++){
for(int j = 0; j < COL; j++){
std::cout << std::setw(2) << mat[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}

Non-repeating random numbers in vector C++

I'm trying to store random numbers in vector, but I want each number to be unique. Can I do that with for loop without using unique() or random_shuffle() ?
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
vector<int> v;
for (unsigned int i = 0; i < 30; i++) {
v.push_back(rand() % 30);
}
for (unsigned int j = 0; j < 30; j++) {
cout << v[j] << endl;
}
return 0;
}
The classic Fisher–Yates shuffle can also be used to generate a shuffled vector directly, in one pass
vector<unsigned> v;
for (unsigned i = 0; i < 30; ++i)
{
unsigned j = rand() % (i + 1);
if (j < i)
{
v.push_back(v[j]);
v[j] = i;
}
else
v.push_back(i);
}
You should probably generate vector and just shuffle it:
#include <iostream>
#include <ctime>
#include <utility>
int main()
{
std::srand(static_cast<unsigned int>(std::time(NULL)));
size_t const n = 30;
std::vector<int> v(n);
//make vector
for (size_t i = 0; i < n; ++i)
v[i] = static_cast<int>(i);
//shuffle
for (size_t i = n - 1; i > 0; --i)
std::swap(v[i], v[static_cast<size_t>(rand()) % (i + 1)]);
//print
for (size_t i = 0; i < n; ++i)
std::cout << (i > 0 ? "," : "") << v[i];
return 0;
}
Prints, for example:
27,24,2,23,13,6,9,14,11,5,15,18,16,29,22,12,26,20,10,8,28,25,7,4,1,17,0,3,19,21

OpenMP code is aborted

I'm trying to perform matrix multiplication using openMP as follows and I compile it using GCC : g++ -std=gnu++11 -g -Wall -fopenmp -o parallel_not_opt parallel_not_opt.cpp
But when I try to run it by using parallel_not_opt.exe, it aborts giving the typical Windows error parallel_not_opt.exe has stopped working...
Am I missing something?
#include "includes/stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
# include <omp.h>
#include <chrono>
#include <fstream>
#include <algorithm>
#include <immintrin.h>
#include <cfloat>
#include <limits>
#include <math.h>
using namespace std::chrono;
using namespace std;
//populate matrix with random values.
double** generateMatrix(int n){
double max = DBL_MAX;
double min = DBL_MIN;
double** matA = new double*[n];
for (int i = 0; i < n; i++) {
matA[i] = new double[n];
for (int j = 0; j < n; j++) {
double randVal = (double)rand() / RAND_MAX;
matA[i][j] = min + randVal * (max - min);
}
}
return matA;
}
//generate matrix for final result.
double** generateMatrixFinal(int n){
double** matA = new double*[n];
for (int i = 0; i < n; i++) {
matA[i] = new double[n];
for (int j = 0; j < n; j++) {
matA[i][j] = 0;
}
}
return matA;
}
//matrix multiplication - parallel
double matrixMultiplicationParallel(double** A, double** B, double** C, int n){
int i, j, k;
clock_t begin_time = clock();
# pragma omp parallel shared ( A,B,C,n ) // private ( i, j, k )
{
# pragma omp for
for (i = 0; i < n; i++) {
// cout<< i << ", " ;
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
double t = float(clock() - begin_time);
return t;
}
int _tmain(int argc, _TCHAR* argv[])
{
ofstream out("output.txt", ios::out | ios::app);
out << "--------------STARTED--------------" << "\n";
int start = 200, stop = 2000, step = 200;
for (int n = start; n <= stop; n += step)
{
srand(time(NULL));
cout << "\nn: " << n << "\n";
double t1 = 0;
int my_size = n;
double **A = generateMatrix(my_size);
double **B = generateMatrix(my_size);
double **C = generateMatrixFinal(my_size);
double single_sample_time = matrixMultiplicationParallel(A, B, C, n);
t1 += single_sample_time;
for (int i = 0; i < n; i++) {
delete[] A[i];
delete[] B[i];
delete[] C[i];
}
delete[] A;
delete[] B;
delete[] C;
}
out << "-----------FINISHED-----------------" << "\n";
out.close();
return 0;
}
The private ( i, j, k ) declaration is not optional. Add it back, otherwise the inner loop variables j and k are shared, which completely messes up the inner loops.
It is better to declare variables as locally as possible. That makes reasoning about OpenMP code much easier:
clock_t begin_time = clock();
# pragma omp parallel
{
# pragma omp for
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
return float(clock() - begin_time);
In that case, A,B,C will be shared by default - coming from the outside, and j,k are private because they are declared within the parallel scope. The loop variable of a parallel for is always implicitly private.