Floating point exception - c++

#include <cstdio>
#include <ctime>
int populate_primes(int array[])
{
const int max = 1000000;
char numbers[max+1];
int count=1;
array[0]=2;
for(int i=max;i>0;i-=2)numbers[i]=0;
for(int i=max-1;i>0;i-=2)numbers[i]=1;
int i;
for(i=3;i*i<=max;i+=2){
if(numbers[i]){
for(int j=i*i;j<max+1;j+=i)numbers[j]=0; array[count++]=i;
}
}
int limit = max/2;
for(;i<limit;i++) if(numbers[i])array[count++]=i;
return count;
}
int factorize(int number,int array[])
{
int i=0,factor=1;
while(number>0){
if(number%array[i]==0){
factor++;
while(number%array[i]==0)number/=array[i];
}
i++;
}
printf("%d\n",factor);
return factor;
}
int main()
{
int primes[42000];
const int max = 1000000;
int factors[max+1];
clock_t start = clock();
int size = populate_primes(primes);
factorize(1000,primes);
printf("Execution time:\t%lf\n",(double)(clock()-start)/CLOCKS_PER_SEC);
return 0;
}
I am trying to find the no. of factors using simple algo. The populate primes part is running okay , but the factorize part does not execute and gives the floating point exception error.
Please see the code and tell my mistake.

In your factorize method you access array[0], because the initial value of i is 0.
This array is the primes array which is populated by populate_primes. But populates prime doesn't write to primes[0], since the initial value of count is 1.
Thus the first element is not initialized and you probably get a div by 0 error.

You need to pass the size which you got from populate to factorize.
factorize(int number, int array[], int size);
problem is your array[] is not fully loaded, it is loaded only till size variable. So you may want to check for that.
Also the logic inside factorize is wrong. You need to check (number > 1) rather than (number >0).

Try with the function below to see some problems:
#define MAX_PRIMES 42000
int factorize(int number,int array[])
{
int i=0,factor=1;
for (i=0; number>0 && i< MAX_PRIMES; i++){
if (array[i] == 0 || array[i] == 1) {
printf("Error: array[%d] = %d\n", i, array[i]);
} else {
if(number%array[i]==0){
factor++;
while(number%array[i]==0 && number>0) {
printf("%d %d\n", number, array[i]);
number/=array[i];
}
}
}
}
printf("%d\n",factor);
return factor;
}

Related

Algorithm crashing

int function(int A[], int n)
{
int i = 0;
int sum = 0;
int amount = 0;
while(i<n) {
if(A[i] > 0) {
sum=sum+A[i];
amount++;
}
else {
i++;
}
}
while(!(i<n)) {
if(ile>0){
return sum/amount;
} else {
return 0;
}
}
}
I am generating random array of numbers between 0-10 , Im trying to use this with this algorithm, but all the time im getting result 6422260. Can someone tell me how should I approach this?
int n;
cin >> n;
int arr[n];
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
arr[i] = rand() % 10;
}
function(arr, n);
Here is a solution to your problem:
#include <random>
#include <iostream>
void fill(int arr[]);
int random(int from, int to);
using namespace std;
int main(void)
{
int arr[10];
fill(arr);
for(int i = 0; i<10; i++)
printf("%d ", arr[i]);
return 0;
}
void fill(int arr[]){
for(int i=0;i<(*(&arr + 1) - arr);i++){
arr[i] = random(0, 10);//adjust accordngly
}
}
int random(int from, int to){
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist6(from, to); // distribution in range [from, to]
return dist6(rng);
}
Your problem is you are not generating random numbers your algorithm is generating the same set of numbers! You need a logic to generate random number. Usually they are generated from system time ...
Attribution : https://stackoverflow.com/a/13445752/14911094
#alkantra, your problem is not generating random numbers. Basically, you are asking your question wrong. If required, it should be separated:
What's this code doing?
How to generate a random sequence?
The algorithm you are trying to achieve is for calculating arithmetic mean (or simply average). If you remember the formula for calculating arithmetic mean you learnt in school, the formula is:
arithmetic mean = sum/n
where
sum - sum of all numbers (from the given array[] of course)
n - count of the numbers in the given array[]
The purpose of the sum variable is to sum all given numbers, if not equal to 0, and n(in your code amount) just increases for every number added to sum.
And in the end the function should return, as the formula says, sum/amount. I could write this code, i.e. the whole program (except for the random()), though it's quite easy, so I'll leave it up to you.
About the random library, I don't know much, but there are may resources on the net, so take your time.
https://www.tutorialspoint.com/cplusplus-program-to-generate-random-number
https://www.tutorialspoint.com/rand-and-srand-in-c-cplusplus

C++ Counting inversions in array, Fatal Signal 11 (BIT)

I was given this challenge in a programming "class". Eventually I decided to go for the "Binary Indexed Trees" solution, as data structures are a thing I'd like to know more about. Implementing BIT was somewhat straight forward, things after that - not so much. I ran into "Fatal Signal 11" when uploading the solution to the server, which, from what I've read, is somewhat similar to a Null pointer exception. Couldn't figure out the problem, decided to check out other solutions with BIT but stumbled upon the same problem.
#include<iostream>
using namespace std;
/* <BLACK MAGIC COPIED FROM geeksforgeeks.org> */
int getSum(int BITree[], int index){
int sum = 0;
while (index > 0){
sum += BITree[index];
index -= index & (-index);
}
return sum;
}
void updateBIT(int BITree[], int n, int index, int val){
while (index <= n){
BITree[index] += val;
index += index & (-index);
}
}
/* <BLACK MAGIC COPIED FROM geeksforgeeks.org> */
int Count(int arr[], int x){
int sum = 0;
int biggest = 0;
for (int i=0; i<x; i++) {
if (biggest < arr[i]) biggest = arr[i];
}
int bit[biggest+1];
for (int i=1; i<=biggest; i++) bit[i] = 0;
for (int i=x-1; i>=0; i--)
{
sum += getSum(bit, arr[i]-1);
updateBIT(bit, biggest, arr[i], 1);
}
return sum;
}
int main(){
int x;
cin >> x;
int *arr = new int[x];
for (int temp = 0; temp < x; temp++) cin >> arr[temp];
/*sizeof(arr) / sizeof(arr[0]); <-- someone suggested this,
but it doesn't change anything from what I can tell*/
cout << Count(arr,x);
delete [] arr;
return 0;
}
I am quite stumped on this. It could be just some simple thing I'm missing, but I really don't know. Any help is much appreciated!
You have condition that every number lies between 1 and 1018. So, your biggest number can be 1018. This is too much for the following line:
int bit[biggest+1];

Equal elements in an unsorted array

I am making a program to identify whether a 5 card ( user input ) array is a certain hand value. Pair, two pair, three of a kind, straight, full house, four of a kind ( all card values are ranked 2-9, no face cards, no suit ). I am trying to do this without sorting the array. I am currently using this to look through the array and identify if two elements are equal to each other
bool pair(const int array[])
{
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
}
Does this section of code only evaluate whether the first two elements are the same, or will it return true if any two elements are the same? I.E if the hand entered were 2,3,2,4,5 would this return false, where 2,2,3,4,5 would return true? If so, how do I see if any two elements are equal, regardless of order, without sorting the array?
edit: please forgive the typos, I'm leaving the original post intact, so as not to create confusion.
I was not trying to compile the code, for the record.
It will do neither:
i < array will not work, array is an array not an int. You need something like int arraySize as a second argument to the function.
Even if you fix that then this; array[i]==aray[i+1] will cause undefined behaviour because you will access 1 past the end of the array. Use the for loop condition i < arraySize - 1.
If you fix both of those things then what you are checking is if 2 consecutive cards are equal which will only work if the array is sorted.
If you really cant sort the array (which would be so easy with std::sort) then you can do this:
const int NumCards = 9; // If this is a constant, this definition should occur somewhere.
bool hasPair(const int array[], const int arraySize) {
int possibleCards[NumCards] = {0}; // Initialize an array to represent the cards. Set
// the array elements to 0.
// Iterate over all of the cards in your hand.
for (int i = 0; i < arraySize; i++) {
int myCurrentCard = array[i]; // Get the current card number.
// Increment it in the array.
possibleCards[myCurrentCard] = possibleCards[myCurrentCard] + 1;
// Or the equivalent to the above in a single line.
possibleCards[array[i]]++; // Increment the card so that you
// count how many of each card is in your hand.
}
for (int i = 0; i < NumCards; ++i) {
// If you want to check for a pair or above.
if (possibleCards[i] >= 2) { return true; }
// If you want to check for exactly a pair.
if (possibleCards[i] == 2) { return true; }
}
return false;
}
This algorithm is actually called the Bucket Sort and is really still sorting the array, its just not doing it in place.
do you know the meaning of return keyword? return means reaching the end of function, so in your code if two adjacent values are equal it immediately exits the function; if you want to continue checking for other equality possibilities then don't use return but you can store indexes of equal values in an array
#include <iostream>
using namespace std;
int* CheckForPairs(int[], int, int&);
int main()
{
int array[ ]= {2, 5, 5, 7, 7};
int nPairsFound = 0;
int* ptrPairs = CheckForPairs(array, 5, nPairsFound);
for(int i(0); i < nPairsFound; i++)
{
cout << ptrPairs[i] << endl;
}
if(ptrPairs)
{
delete[] ptrPairs;
ptrPairs = NULL;
}
return 0;
}
int* CheckForPairs(int array[] , int size, int& nPairsFound)
{
int *temp = NULL;
nPairsFound = 0;
int j = 0;
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
nPairsFound++;
}
temp = new int[nPairsFound];
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
{
temp[j] = i;
j++;
}
}
return temp;
}
You could use a std::unordered_set for a O(n) solution:
#include <unordered_set>
using namespace std;
bool hasMatchingElements(const int array[], int arraySize) {
unordered_set<int> seen;
for (int i = 0; i < arraySize; i++) {
int t = array[i];
if (seen.count(t)) {
return true;
} else {
seen.insert(t);
}
}
return false;
}
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
This loop will only compare two adjacent values so the loop will return false for array[] = {2,3,2,4,5}.
You need a nested for loop:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int unsortedArray[] = {2,3,2,4,5};
int size = 5;
for(int i=0;i<size-1;i++)
{ for(int j=i+1;j<size;j++)
{ if(unsortedArray[i]==unsortedArray[j])
{ printf("matching cards found\n");
return 0;
}
}
}
printf("matching cards not found\n");
return 0;
}
----EDIT------
Like Ben said, I should mention the function above will only find the first instance of 2 matching cards but it can't count how many cards match or if there are different cards matching. You could do something like below to count all the number of matching cards in the unsortedArray and save those values into a separate array. It's messier than the implementation above:
#include <iostream>
#include <stdio.h>
#include <stdbool.h>
#defin NUM_CARDS 52;
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int N,i,j;
cin>>N;
int unsortedArray[N];
for(int i=0;i<N;i++)
cin>>unsortedArray[i];
int count[NUM_CARDS]={0};
int cnt = 0;
for( i=0;i<N-1;i++)
{
for( j=i+1;j<N;j++)
{ if(unsortedArray[i]==-1)
break;
if(unsortedArray[i]==unsortedArray[j])
{
unsortedArray[j]=-1;
cnt++;
}
}
if(unsortedArray[i]!=-1)
{
count[unsortedArray[i]]=cnt; //in case you need to store the number of each cards to
// determine the poker hand.
if(cnt==1)
cout<<" 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else if(cnt>=2)
cout<<" more than 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else
cout<<" no matching cards of "<<unsortedArray[i]<<" was found"<<endl;
cnt = 0;
}
}

bubble sorting an array using recursion (no loops) c++

#include <iostream>
#include <cstdlib>
using std:: cin;
using std:: cout;
using std:: endl;
const int N=10;
void readarray(int array[], int N);
int bubble_sort (int array[], int size, int round,
int place);
int main ()
{
int array[N];
readarray( array, N );
int round, place;
cout << bubble_sort(array, N, place, round);
return EXIT_SUCCESS;
}
void readarray(int array[], int N)
{
int i=0;
if (i < N)
{
cin >> array[i];
readarray(array+1, N-1);
}
}
int bubble_sort (int array[], int size, int round,
int place)
{
round =0;
place =0;
if (round < N-1) // this goes over the array again making sure it has
// sorted from lowest to highest
{
if (place < N - round -1) // this sorts the array only 2 cells at a
// time
if (array[0] > array[1])
{
int temp = array[1];
array[1]=array[0];
array[0]=temp;
return (array+1, size-1, place+1, round);
}
return (array+1, size-1, place, round+1);
}
}
I know how to do a bubble sort using two for loops and I want to do it using recursion. Using loops you require two for loops and I figured for recursion it might also need two recursive functions/calls. This is what I have so far. The problem is that its outputting only one number, which is either 1 or 0. I'm not sure if my returns are correct.
In c++11, you can do this:
#include <iostream>
#include <vector>
void swap(std::vector<int &numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(std::vector<int> &numbers, size_t at)
{
if (at >= numbers.size() - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(std::vector<int> &numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
std::vector<int> numbers = {1,4,3,6,2,3,7,8,3};
bubble_sort(numbers);
for (size_t i=0; i != numbers.size(); ++i)
std::cout << numbers[i] << ' ';
}
In general you can replace each loop by a recursive function which:
check the guard -> if fail return.
else execute body
recursively call function, typically with an incremented counter or something.
However, to prevent a(n actual) stack overflow, avoiding recursion where loops are equally adequate is good practice. Moreover, a loop has a very canonical form and hence is easy to read for many programmers, whereas recursion can be done in many, and hence is harder to read, test and verify. Oh, and recursion is typically slower as it needs to create a new stackframe (citation needed, not too sure).
EDIT
Using a plain array:
#include <iostream>
#include <vector>
#define N 10
void swap(int *numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(int *numbers, size_t at)
{
if (at >= N - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(int *numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
int numbers[N] = {1,4,3,6,2,3,7,8,3,5};
bubble_sort(numbers);
for (size_t i=0; i != N; ++i)
std::cout << numbers[i] << ' ';
}
Please read this post
function pass(i,j,n,arr)
{
if(arr[i]>arr(j))
swap(arr[i],arr[j]);
if(j==n)
{
j=0;
i=i+1;
}
if(i==n+1)
return arr;
return pass(i,j+1,n,arr);
}

Dynamic memory allocation in merge sort

I wrote a program for merge sort (i wrote the basic algorithm) - and it works fine. However, since I have to read the integers from a very large file I wanted to declare the array dynamically in the recursive calls . hence i wrote the following code , however it is giving me some errors, could you please help me identify where i am making the mistake?
The program is actually to count the number of inversions in an array ( if i < j and arr[i]>arr[j] , then this is an inversion). The program I have written is as below :
I dont want to declare a array of 10000 integers on stack everytime i go in recursive calls
The error i get is : std::bad_alloc at memory location 0x004dd940..
i have edited the question so it includes the error message. The execution breaks and visual studio goes into debug mode and opens a file osfinfo.c
#include<stdio.h>
#include <iostream>
using namespace std;
unsigned int mixAndCount(int * arr,int low, int mid,int high) {
int *num = new int[high-low+1];// THIS IS WHERE THE ERROR OCCURS
int l = low ;
int r = mid+1;
unsigned int count=0;
int i =low;
while((l<=mid)&&(r<=high))
{
if(arr[l]<=arr[r])
{
num[i]=arr[l];
l++;
}
else
{
num[i]=arr[r];
r++;
count=count + (mid-l+1);
}
i++;
}
if(l>mid)
{
for(int k=r;k<=high;k++)
{
num[i]=arr[k];
i++;
}
}
else
{
for(int k=l;k<=mid;k++)
{
num[i]=arr[k];
i++;
}
}
for(int k=low;k<=high;k++) arr[k]=num[k];
delete[] num;
return count;
}
unsigned int mergeAndCount(int * arr, int low , int high ) {
if(low>=high) {
return 0;
}
else {
int mid = (low+high)/2;
unsigned int left = mergeAndCount(arr, low , mid);
unsigned right = mergeAndCount(arr, mid+1, high);
unsigned int split = mixAndCount(arr, low , mid , high);
return left+right+split;
}
}
int main ()
{
int numArr[100000];
FILE * input = fopen("IntegerArray.txt", "r");
int i =0;
while(!feof(input)) {
int num;
fscanf(input, "%d", &num);
numArr[i] = num;
i++;
}
fclose(input);
unsigned int count = mergeAndCount(numArr,0, i-1 );
cout<<count<<endl;
return 0;
}
std::bad_alloc at memory location 0x004dd940..
Is an exception thrown by new when it cannot allocate requested memory successfully.
int *num = new int[high-low+1];
It seems the requested memory size is too large, which means you need to track values of high, low.
Be aware of dynamic memory allocation. Its really slower. Consider twice before you will leave your code in this form. You can make a simple testcase with std::chrono
http://en.cppreference.com/w/cpp/chrono/duration
you dont need dynamic allocation, everything is done in one local namespace.