I think the problem is with the for-loop but I cannot understand it. This is an assignment in school that I only should use for-loops and if statements to solve!
#include <stdio.h>
int is_prime(int n){
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
};
}
int main(void){
printf("%d\n", is_prime(11)); // 11 is a prime. Should print 1.
printf("%d\n", is_prime(383)); // 383 is a prime. Should print 1.
printf("%d\n", is_prime(987)); // 987 is not a prime. Should print 0.
}
For starters the null statement after the if statement and the for loop itself
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
^^^
};
^^^
is redundant.
Due to the if statement the for loop is interrupted as soon as either n % i is not equal to 0 or is equal to 0. So in general the behavior of the function does not depend on whether the passed number is prime or not prime.
If you will move the return statement
return 1;
outside the loop as others advised nevertheless the function will be still incorrect. It will show that 0 and 1 are prime numbers while they are not.
Also the condition of the loop makes the loop inefficient at least because it is clear before entering the loop that any even number except 2 is not a prime number.
Pay attention to that the function parameter should have unsigned integer type.
The function can be defined the following way
#include <stdio.h>
int is_prime( unsigned long long int n )
{
int prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main(void)
{
printf( "%d\n", is_prime( 11 ) );
printf( "%d\n", is_prime( 383 ) );
printf( "%d\n", is_prime( 987 ) );
return 0;
}
The program output is
1
1
0
The problem is return 1 inside the loop. When you find one i that is not a factor of n, you assume n to be prime. But you have to ensure that all i are not a factor of prime, so the return 1 must be placed after the loop. However, that would cause numbers < 2 to be considered prime, as they do not enter the loop at all. Therefore, you also have to add an additional if at the beginning.
By the way: Every divisor of n (expect n itself) must be <= sqrt(n), therefore you can speed up your function quite a bit.
#include <math.h>
int is_prime(int n) {
if (n < 2)
return 0;
int max_divisor = sqrt(n);
for (int i = 2; i <= max_divisor; i++) {
if (n % i == 0)
return 0;
}
return 1;
}
Problem: return statement
return 1;
}
else{
return 0;
It causes the loop to exit then and there. In your case too, it exits as soon as the first '1' is achieved.
Solution: Instead you should try to store the values in a variable and compare with '1' or '0' at the end of loop
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
A customer points at some kind of sweets and gives several banknotes to the seller. This means that he wants to buy a positive number of sweets of that kind. He doesn't tell the exact number of sweets he wants to buy. The only thing Ann knows is: an 'adequate' customer won't give any extra banknotes. It means that if you throw away any banknote, the resulting amount of money won't be enough to buy the wanted number of sweets.
Ann has to determine the number of sweets the customer wants. Help Ann write a program which determines this number or tells that it's impossible.
Input
The first line of the input contains a single integer T, the number of test cases (no more than 20). T test cases follow. Each test case consists of two lines. The first of these lines contains two integers N and X (1 ≤ N, X ≤ 100) separated by a single space. N is the number of banknotes given by the customer. X is the cost of a single sweet of the chosen kind. The second of these lines contains N space-separated integers Ai (1 ≤ Ai ≤ 100), the values of the banknotes.
#include "stdafx.h"
int main(void)
{
int n = 2, x=10;
int a[2] = { 20,50};
int sum = 0;
int min = a[0];
for (int i = 0; i <= n; i++)
{
sum = sum + a[i];
if (min>a[i + 1])
{
min = a[i];
}
}
printf("%d %d\n", sum, min);//output -858993390, -858993460
int y= sum % x;
int k = sum / x;
if (y- min > 0)
printf( "-1");// output -1
else
printf( "%d\n",k);
return 0;
}
for (int i = 0; i <= n; i++) should be for (int i = 0; i < n; i++). You have allocated array size of 2. That means you have control over index 0 and 1. But you are trying to access index 2.
this line, even after the correction of the 'for' statement, will access beyond the end of the a[] array, resulting in undefined behavior.
if (min>a[i + 1])
The posted code, even if these two errors are corrected, does not implement the problem set.
caveat: The following code assumes that all values are integers
comments within the code indicate each step being performed
/*
* ***********************************************************************************************
The first line of the input contains a single integer T, the number of test cases (no more than 20).
T test cases follow.
Each test case consists of two lines.
The first of these lines contains two integers N and X (1 ≤ N, X ≤ 100) separated by a single space.
.... N is the number of banknotes given by the customer.
.... X is the cost of a single sweet of the chosen kind.
The second of these lines contains N space-separated integers Ai (1 ≤ Ai ≤ 100), the values of the banknotes
* ************************************************************************************************
*/
#include <stdio.h> // scanf(), perror(), printf()
#include <stdlib.h> // exit(), EXIT_FAILURE
int main( void )
{
// input number of test cases
int testCases;
if( 1 != scanf( "%d", &testCases ) )
{
perror( "scanf for number of test cases failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
for( ; testCases; testCases-- )
{
int numNotes;
int eachCost;
//get N_X line
if( 2 != scanf( "%d %d", &numNotes, &eachCost ) )
{
perror( "scanf for numNotes and eachCost failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// read bank notes and calculate sum
int totalNotes = 0;
int singleNote;
for( int j=0; j < numNotes; j++ )
{
if( 1 != scanf( "%d", &singleNote ) )
{
perror( "scanf for single note failed" );
exit( EXIT_FAILURE );
}
totalNotes += singleNote;
} // end for each bank note
// calculate number of candies that can be purchased,
// given the totalNotes and eachCost
if( totalNotes >= eachCost )
{
int numCandies = totalNotes / eachCost;
printf( "Number of candies: %d\n", numCandies );
}
else
{
printf( "not enough notes to purchase any candies\n" );
}
// follow each test case with a blank line
printf( "\n" );
} // end for each test case
} // end function: main
How come do I get a message "Command terminated" when I try to input a large number (around 10 million)? The program displays whether the number is a prime or not.
See code below:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int main ( int argc, char *argv[] )
{
unsigned long long number;
bool prime ( unsigned long long );
printf ("Enter a positive integer greater than 1: ");
scanf ("%llu", &number );
prime( number ) ?
printf ( "%llu is a prime.\n", number ):
printf ( "%llu is not a prime.\n", number);
return EXIT_SUCCESS;
}
bool prime ( unsigned long long number )
{
unsigned long long i, j;
bool isPrime[number + 1];
for ( i = 2; i <= number; i++ )
isPrime[i] = true;
for ( i = 2; i <= number - 1; i++ )
for ( j = 1; i*j <= number; j++ )
isPrime[i*j] = false;
return isPrime[number];
}
The problem is that you attempt to create an array isPrime on the stack that is larger than the available memory. You should create it on the heap instead, using
bool *isPrime;
isPrime = malloc((number + 1) * sizeof *isPrime);
do this only once obviously, not for every call to the function prime
Notice also that if you just want to know if a number is prime, you only need to search as far as the square root of the number for a factor - and if you find a factor you are done. This makes the size of the array you have to create much more manageable - but it does involve some changes to your algorithm.
afterthought you have a problem in the logic that determines what is a prime number - your inner loop starts with j=1 which means that even prime numbers will be marked as non-prime. The following is "slightly improved" code - although there's more you could do to make it much better:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
int main ( int argc, char *argv[] )
{
unsigned long long number;
bool prime ( unsigned long long );
printf ("Enter a positive integer greater than 1: ");
scanf ("%llu", &number );
prime( number ) ?
printf ( "%llu is a prime.\n", number ):
printf ( "%llu is not a prime.\n", number);
return EXIT_SUCCESS;
}
bool prime ( unsigned long long number )
{
unsigned long long i, j, sq;
bool *isPrime;
sq = ceil(sqrt(number));
isPrime = malloc((sq + 1)*sizeof *isPrime);
// generate primes up to the square root of the number
for ( i = 2; i <= sq; i++ )
isPrime[i] = true;
for ( i = 2; i < sq; i++ ) {
// only need to mark multiples if this is a prime:
if(isPrime[i]) {
// start this loop at 2, not 1!
for ( j = 2; i*j <= sq; j++ ) {
isPrime[i*j] = false;
}
}
}
for ( i = 1; i < sq; i++)
{
if (isPrime[i] && number%i==0) return false;
}
return true;
}
Basic testing:
gcc -Wall generates no errors / warnings
104729 is a prime (it is); code doesn't crash with an input of 10000001 (not a prime).
I'm working on implementing a parallel algorithm of the Sieve Of Erastothenes in C using BSP.
My code compiles and executes but doesn't print the primes.
When I do ./bspsieve 2 1000 for example the only output I get is
"It took : 0.000371 seconds for proc 0 out of 2." while it should be printing all the found primes!
Oddly enough the algorithm does work it seems like. If I use a larger upperbound in the above example, it takes longer. When I assign more processors, it takes less time. So probably a stupid mistake somewhere, but I have serious problems with C and am working on a remote computer so unsure of that tools I've got...
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mcbsp.h>
/*
Note: To compile, this file has to be in the same folder as mcbsp.h and you need the 2 following commands:
gcc -Iinclude/ -pthread -c -o bspsieve.o bspsieve.c
gcc -o bspsieve bspsieve.o lib/libmcbsp1.1.0.a -lpthread -lrt
*/
int procs;
int upperbound;
int *primes;
//SPMD function
void bspSieve(){
bsp_begin(procs);
int p = bsp_nprocs(); // p = number of procs obtained
int s = bsp_pid(); // s = proc number
float blocksize; // block size to be used, note last proc has a different size!
if( s != p-1){
blocksize = ceil(upperbound/p);
} else {
blocksize = upperbound - (p-1)*ceil(upperbound/p);
}
// Initialize start time and end time, set start time to now.
double start_time,end_time;
start_time = bsp_time();
// Create vector that has block of candidates
int *blockvector;
blockvector = (int *)malloc(blocksize*sizeof(int));
int q;
for(q = 0; q<blocksize; q++){
//List contains the integers from s*blocksize till blocksize + s*blocksize
blockvector[q] = q + s*blocksize;
}
//We neglect the first 2 'primes' in processor 0.
if(s == 0){
blockvector[0] = 0;
blockvector[1] = 0;
}
// We are using the block distribution. We assume that n is large enough to
// assure that n/p is larger than sqrt(n). This means that we will always find the
// sieving prime in the first block, and so have to broadcast from the first
// processor to the others.
long sieving_prime;
int i;
bsp_push_reg( &sieving_prime,sizeof(long) );
bsp_sync();
for(i = 2; i * i < upperbound; i++) {
//Part 1: if first processor, get the newest sieving prime, broadcast. Search for newest prime starting from i.
if(s == 0){
int findPrimeNb;
for(findPrimeNb = i; findPrimeNb < blocksize; findPrimeNb++) {
if( blockvector[findPrimeNb] != 0) {
sieving_prime = blockvector[findPrimeNb];
//broadcast
int procNb;
for(procNb = 0; procNb < p; ++procNb){
bsp_put(procNb, &sieving_prime,&sieving_prime,0,sizeof(long));
}
break;
}
}
}
bsp_sync();
//Part 2: Sieve using the sieving prime
int sievingNb;
for(sievingNb = 0; sievingNb < blocksize; sievingNb++){
//check if element is multiple of sieving prime, if so, pcross out (put to zero)
if( blockvector[sievingNb] % sieving_prime == 0){
blockvector[sievingNb] = 0;
}
}
}
//part 3: get local primes to central area
int transferNb;
long transferPrime;
for(transferNb = 0; transferNb < blocksize; transferNb++){
transferPrime = blockvector[transferNb];
primes[transferPrime] = transferPrime;
}
// take the end time.
end_time = bsp_time();
//Print amount of taken time, only processor 0 has to do this.
if( s == 0 ){
printf("It took : %.6lf seconds for proc %d out of %d. \n", end_time-start_time, bsp_pid(), bsp_nprocs());
fflush(stdout);
}
bsp_pop_reg(&sieving_prime);
bsp_end();
}
int main(int argc, char **argv){
if(argc != 3) {
printf( "Usage: %s <proc count> <upper bound> <n", argv[ 0 ] );
exit(1);
}
//retrieve parameters
procs = atoi( argv[ 1 ] );
upperbound = atoi( argv[ 2 ] );
primes = (int *)malloc(upperbound*sizeof(int));
// init and call parallel part
bsp_init(bspSieve, argc, argv);
bspSieve();
//Print all non zeros of candidates, these are the primes.
// Primes only go to p*p <= n
int i;
for(i = 0; i*i <= upperbound; i++) {
if(primes[i] > 0) {
printf("%d, ",primes[i]);
}
}
return 0;
}
printf doesn't automatically include a trailing newline, and it doesn't generally flush the output buffer until it outputs a newline; so probably you just need to add a
printf("\n");
at the end of your program, just before your return 0;.
Alternatively, or additionally, if you want to see the output as-you-go (if BSP allows that), you can add a
fflush(stdout);
right after your printf("%d, ",primes[i]);, to explicitly flush the output buffer.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm working on a problem where I'm given a sorted array of integers, and I am supposed to take an input from the user, search for the input, and return the first instance of that input (if it exists) and the number of times it appears.
I wrote a program with the following approach: I take an input from the user. I then use binary search to find the value. If it exists, then I store the index as m. After that, I write two while loops. The first loop checks for the number of occurrences of the value to the left and the second does the same, but to the right. For example, the binary search might be looking for 5, and it finds it. However, it lands on the 3rd one, ie. {.....5,5,**5**,5....}. The first while loop will count the two the the left and the second while loop will count the one to the right. Then I'll sum them all up and return the total number of instances. If the the input value does not exist, then I skip the afore-mentioned code and simply return -1.
In the body of the main function, I then check the return value. If it is -1, I tell the user that the value has not been found. If the return value is >=0, then I print the required info.
Anyways, I have written up the C code for the program, but I cannot get it to work properly. I get a seg. fault error, I don't know what I'm doing wrong though. Anyways, any help would be appreciated. I've been pounding my head on this problem for awhile. It's been interesting and hard, and I think I have the right logic; but I cannot get it to work properly. Anyways, here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
/* function prototype */
int get_num_of_ints( const int* arr, size_t r, int N, size_t* f, size_t* count );
int main()
{
int i;
int N; /* input variable */
int arr[]={1,1,2,3,4,4,4,4,5,5,6,7,7,7,7,8,9,9}; /* array of sorted integers */
size_t r = sizeof(arr[i])/sizeof(int); /* right bound */
size_t f; /* first match index */
size_t *fPtr;
fPtr = &f;
size_t count; /* total number of matches */
size_t *countPtr;
countPtr = &count;
printf( "\nPlease input the integer you would like to find.\n" );
scanf( "%d", &N );
int a = get_num_of_ints( arr, r, N, fPtr, countPtr );
if( a == -1)
printf( "%d has not been found.\n", N );
else if(a >= 0){
printf( "The first index is %d.\n", f );
printf( "The total number of values is %d.\n", count );
}
return 0;
}
/* function definition */
int get_num_of_ints( const int* arr, size_t r, int N, size_t* f, size_t* count )
{
int l = 0;
int m;
int w=r;
size_t *fPtr;
size_t *countPtr;
while(l <= r){
m = l +(r - l)/2;
if(arr[m] < N)
l = m+1;
else if(arr[m] > N)
r = m-1;
else if(arr[m]==N)
m=m;
break;
}
if( l > r)
m = -1;
if( m >= 0 ){
int j = m-1;
int L = 0;
while(arr[j] == arr[m] && j >= 0){
L++;
j--;
}
if( j>= 0 && L > 0 )
*fPtr=j;
else
*fPtr=m;
int h = m + 1;
int R = 0;
while( arr[h]==arr[m] && h <= w ){
R++;
h++;
}
*countPtr = (R + L + 1);
return *fPtr;
}
else if( m==-1)
return -1;
}
while(arr[j] == arr[m] && j >= 0)
You should switch the order of the two conditions here, or you'll try to read arr[-1]. Same thing for the second while loop.
Another problem is that r should start at 1 less than the array size, since arr[array_size] is past the end.
Edit:
A serious problem is that you are writing to the uninitialized pointers countPtr and fPtr when you should be writing to *count and *f. This is probably what's causing the segfault. This would have been easy to spot in a debugger.
Use variable names that mean something. You might find the problem immediately.
Run the program in a debugger and step through the code; you should see where things are going wrong pretty quickly. (Hint, what's fPtr used for in get_num_of_ints? There are other bugs too as others have pointed out).
Since you need the number of occurrences, you need to search through each element, right?
Why not simplify things and just do a linear scan? Here's some pseudocode:
function get_num_of_ints(arr, n){
first_index = -1
count = 0
for(i = 0; i < length(arr); i++)
if(x == n){
count++
if(first_index == -1)
first_index = i
}
return count, first_index
}
I don't have a C compiler in the computer I'm sitting now, so I can't test it, but I see that in the first while-loop of your function you're saying:
else if(arr[m]==N)
m=m;
break;
The break statement is outside the if in this case, so the while loop will execute only once each time.
I don't know if this causes the error though.
The segmentation fault comes from get_num_of_ints() in lines 74, 77, and 87.
if( j>= 0 && L > 0 )
*fPtr=j;
else
*fPtr=m;
...
*countPtr = (R + L + 1);
You have not assigned a memory address to the pointers, and thus you are using an arbitrary memory location in these lines.
It doesn't seem like there's any real reason to be using a pointer for these variables anyway. Try changing them from pointers to size_t to just variables of type size_t.
size_t fPtr;
size_t countPtr;
In get_num_of_ints() function you are using pointer fptr without allocating memory to it.
Thanks to everybody's comments, I was able to find all the bugs in my program, and use the gdb debugger too. Anyways, I no longer have my seg. fault errors when I run the program; however, I have some sort of logic problem becauase when I prompt the user for an input,and say the user types 4, then the outputs for # of occurence and location of first occurrence are garbage values.
I get:
Please input the integer you would like to find.
4
The first index is -1075300456.
The total number of values is 12169204.
This revolves around the issue I had earlier with the last two parameters in my function. At the bottom, in the function definition, I want count to be the total number of occurrences found in the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
/* function prototype */
int get_num_of_ints( const int* arr, size_t r, int N, size_t f, size_t count );
int main()
{
int i;
int N; /* input variable */
int arr[]={1,1,2,3,4,4,4,4,5,5,6,7,7,7,7,8,9,9}; /* array of sorted integers */
size_t r = sizeof(arr)/sizeof(arr[0]) - 1; /* right bound */
size_t f; /* first match index */
size_t count; /* total number of matches */
printf( "\nPlease input the integer you would like to find.\n" );
scanf( "%d", &N );
int a = get_num_of_ints( arr, r, N, f, count );
if( a == -1)
printf( "%d has not been found.\n", N );
else if(a >= 0){
printf( "The first index is %d.\n", f );
printf( "The total number of values is %d.\n", count );
}
return 0;
}
/* function definition */
int get_num_of_ints( const int* arr, size_t r, int N, size_t f, size_t count )
{
int l = 0;
int m;
int w=r;
while(l <= r){
m = l +(r - l)/2;
if(arr[m] < N)
l = m+1;
else if(arr[m] > N)
r = m-1;
else if(arr[m]==N){
m=m;
break;
}
}
if( l > r)
m = -1;
if( m >= 0 ){
int j = m-1;
int L = 0;
while( j >= 0 && arr[j] == arr[m] ){
L++;
j--;
}
if( j>= 0 && L > 0 )
f=j;
else
f=m;
int h = m + 1;
int R = 0;
while( arr[h]==arr[m] && h <= w ){
R++;
h++;
}
count = (R + L + 1);
return f;
}
else if( m==-1)
return -1;
}
As everyone pointed out countPtr and fPtr needs to be allocated with memory
size_t *fPtr = malloc(sizeof(size_t));
Make sure you intialize "i" with some value before using it
Compile the program (if you are in Linux) with # gcc -g -Wall <your c file name> -o arraysort
Start the debugger, step through the code to find out valeues, I found several funny values for r, arr[m],
#gdb ./arraysort
b
run
[inspect variables here]
HTH