I have been attempting to write a program that will determine if a number is prime or not. I have based it off of the Sieve of Eratosthenes. Anyway, my program works for small numbers (15485863 works), but if I use large numbers (ex. 17485863) I receive a segmentation fault. I am using unsigned long longs and do not think I have surpassed their maximum value. I just don't see what I have done wrong. Thank you in advance for any assistance!
#include <iostream>
#include <limits>
using namespace std;
bool soe (unsigned long long);
int main (void)
{
unsigned long long x = 17485863;
bool q = soe(x);
cout << x << " is ";
if(q)
cout << "prime." << endl;
else
cout << "not prime." << endl;
return 0;
}
bool soe(unsigned long long input)
{
unsigned long long arrayLength = input%2 + input/2;
unsigned long long index = 2;
unsigned long long greatestMult = 0;
bool array[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
return false;
}
}while(index < arrayLength);
return true;
}
Please note that neither long long nor using variables to dimension automatic arrays are part of C++ - they are extensions provided by gcc and should not be used if portability is an issue.
To address your problem, dimensioning an array like this:
bool array[arrayLength];
will cause a stack overflow (and thus a seg fault) if the arrayLength value is too large. Use a std::vector instead, but be aware that memory is not an infinite resource.
On Line 24 you have: bool array[arrayLength]; You cannot declare an array on the stack like this. The program is crashing on line 29. You need to declare this on the heap using new/delete;
Something to this effect (I may have a leak or two in there, but you get the idea);
//Beginning on Line 28
bool *array = new bool[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
delete [] array;
return false;
}
}while(index < arrayLength);
delete [] array;
return true;
}
Output
g++ -g test.cpp
gdb ./a.out
...clipped...
(gdb) run
Starting program: /Users/nextraztus/a.out
Reading symbols for shared libraries ++. done
17485863 is divisble by 3
17485863 is not prime.
Program exited normally.
(gdb)
It is possible for index*greatestMult to be equal to arrayLength, so you can overwrite the last element past the array end.
Also allocating large arrays on the stack like that can cause a problem depending on the operating system. Some systems will expand the stack that much, others will not be able to.
Related
if ( n % 2 == 0)
cout << n << " is even.";
else
cout << n << " is odd.";
I know how to check if the numbers are odd, but unsure of how to write the rest of the code.
bool isOdd(int int_arr[], int arr_size)
{
bool is_all_odd = true;
for(int i = 0; i < arr_size; i++)
{
if(int_arr[i] % 2 == 0)
{
is_all_odd = false;
break;
}
}
return is_all_odd;
}
You'll want to take in the array like you mentioned, the size, and traverse through it. In this case we just assume all is odd, and check for an even, if we find an even number we change the return value, stop traversing and return.
My code doesn't seem to work and I cannot understand why.
When the user enters a number to search for its location it doesn't show anything. If anyone could explain it to me I would greatly appreciate it.
void Array::binarySearch(vector<int> vect)
{
int search_val;
int high = (int)vect.size();
int low = 0;
int mid = 0;
bool found = false;
cout << "Enter Number to search : ";
cin>>search_val;
while (low <= high && !found) {
mid = (high + low)/2;
if (search_val > vect[mid]) {
low = mid + 1;
} else if (search_val < vect[mid]) {
high = mid - 1;
} else {
cout << "Number you entered " << search_val << " was found in position " << mid << endl;
found = true;
}
}
if (!found) {
cout << " The value isn't found " << endl;
}
}
sorted algo:
void Array::arrSort(vector<int> vect)
{
for (unsigned int i = 0; i < vect.size()-1; i++)
{
for (unsigned int j = 0; j < vect.size()-i-1; j++)
{
if (vect[j] > vect[j+1])
{
int x = vect[j+1];
vect[j+1] = vect[j];
vect[j] = x;
}
}
}
cout<<"Sorted output is "<<endl;
printArr(vect);
}
Your arrSort function takes its parameter by value, so it receives (and sorts) a copy of the original array.
To sort the array you're passing in, take the parameter by reference:
void Array::arrSort(vector<int> &vect)
As someone has pointed out, you must ensure that you are performing binary search on a sorted array. Perhaps, you should build and test each algorithm separately to ensure correctness before combining them together.
Check out std::sort to get your binary search function working, then work on your sort function––or vice versa.
Also, if you have found the item you are looking for say, vect[mid] == search_val you can go ahead and return true (or print like you've done) and terminate the algorithm.
This code is trying to check if a number is prime, I know there are more efficient methods, using sets of numbers, but I just want this to work, but I get a Segmentation fault.
If you want to test the code, it happens to me when I plug in 10000877, or any greater number.
#include <math.h>
#include <iostream>
int main () {
int prime/*???*/;
std::cout << "Please input a number: ";
std::cin >> prime;
bool isPrime = true;
int biggestFactor = ceil((prime^(1/2)));
bool odd = prime%2 == 1 ? true : false;
int multiple = 0;
int ranges[biggestFactor];
bool boolean = false;
for(int i = biggestFactor; i!=1; i--) {
ranges[i-2] = ceil(prime / i);
}
if(odd) {
for(int i = 1; i<prime; i++) {
if(multiple > biggestFactor) {
break;
} else if(boolean) {
} else if(i* ranges [multiple] > prime) {
multiple++;
} else if(i*ranges[multiple] == prime) {
isPrime = false;
break;
}
}
} else {
if(prime != 2) {
isPrime = false;
}
}
if(isPrime) {
std::cout << "That number is prime." << std::endl;
} else {
std::cout << "That number is composite." << std::endl;
}
}
Aside from noted fact that prime^(1/2) is not square root of prime, your code (even though it's wrong) sort of works. You just overestimate the square root by using prime instead (the 1/2 is converted to int which is 0 and XOR with it is itself).
It works on small numbers, I tried.
Now with the large numbers you are running out of memory here, trying to allocate 4 * 10000877 bytes
int ranges[biggestFactor];
Question: How to find, for a given integer n, the first prime number that is larger than n?
My own work so far
I've managed to write a program that checks whether or not a given integer is a prime or not:
#include <iostream>
#include <cmath>
using namespace std;
bool is_prime (int n)
{
int i;
double square_root_n = sqrt(n) ;
for (i = 2; i <= square_root_n ; i++)
{
if (n % i == 0){
return false;
break;
}
}
return true;
}
int main(int argc, char** argv)
{
int i;
while (true)
{
cout << "Input the number and press ENTER: \n";
cout << "To exit input 0 and press ENTER: \n";
cin >> i;
if (i == 0)
{
break;
}
if (is_prime(i))
cout << i << " is prime" << endl;
else
cout << i << " isn't prime'" << endl;
}
return 0;
}
I'm struggling, however, on how to proceed on from this point.
You have a function is_prime(n), and a number n, and you want to return the smallest number q such that is_prime(q)==true and n <= q:
int q = n;
while (!is_prime(q)) {
q++;
}
// here you can be sure that
// 1. q is prime
// 2. q >= n -- unless there was an overflow
If you want to be a bit more efficient, you can check explicitly for the even case, and the increment by 2 each time.
It's a concrete example of a general theme: if you have a test function and a method for generating elements, you can generate the elements that pass the test:
x = initial_value
while (something) {
if (test(x)) {
// found!
// If you only want the first such x, you can break
break;
}
x = generate(x)
}
(note that this is not a valid C++ code, it's pseudocode)
int i;
**int k_koren_od_n = (int)(sqrt(n) + 0.5)**
for (i = 2; i <= k_koren_od_n ; i++){
To get around casting issues, you might want to add this fix.
I'm trying to write a function that detects the number the negative integers in a stack recursively. Currently the snippet below is what I have, however it is not giving the correct answer so far. I tested with a stack of 11 elements with 7 negatives and got the output given below. There is definitely something wrong with the loop structure but I have not been able to pinpoint and fix it yet. Any help will be appreciated!
12356657235681623569772357137235729723574562357617235777623579372358096
My function below:
size_t r_func(stack<int> st1)
{
if(st1.size() == 0) return 0;
int r = st1.top();
st1.pop();
cout << (r<0)+r_func(st1);
}
size_t r_func(stack<int> st1)
{
if(st1.size() == 0) return 0;
int r = st1.top();
st1.pop();
cout << (r<0)+r_func(st1);
}
r_func is supposed to return a size_t, but if st1.size() is not zero then it won't return anything. The compiler should've given you a warning about this!
To correct this, add a line that returns the number of negative numbers in your stack:
...
st1.pop();
const size_t neg_count = (r < 0) + r_func(st1);
cout << neg_count;
return neg_count;
}
Edit: To write this tail-recursively, it's necessary to keep track of the size in an accumulator (here it's called neg_accum):
size_t r_func(stack<int> st1, size_t neg_accum = 0)
{
if (st1.size() == 0) {
cout << neg_accum;
return neg_accum;
}
int r = st1.top();
st1.pop();
return r_func(st1, (r < 0) + neg_accum);
}
As Rufflewind said, you should replace 'cout <<' with 'return' and call your function in this way: 'cout << r_func(st1);'