How to make a C program run faster? [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have to calculate the number of prime numbers in the interval from 0 to N. The problem is that the program runs very slowly when N > 100000.
int main(){
long int i, j, n,isPrime;
long int N, count;
N = 10000000;
count = 0;
for(i = 2; i <= N; i++){
isPrime = 0;
for(j = 2; j <= i/2; j++){
if(i % j == 0){
isPrime = 1;
break;
}
}
if(isPrime==0 && N!= 1)
/*printf("%d ",i);*/
if(isPrime==0 && N!= 1)
count++;
}
printf(" %li ", count);
getch();
return 0;
}

you don't have to go up to i/2 to look for the prime, just look up to the square root. Any divisors greater that the square root aren't useful: you'd have already found their counterpart before.
int sqr = int(sqrt(i)); // make sure it is computed only once
for(j = 2; j <= sqr; j++){
that should do it...
or (as suggested) compare squares to avoid computing sqrt at all
for(j = 2; j*j <= i; j++){
That method is good to find if a big number is prime. But to find a range of prime numbers, you'd be better off with a Sieve of Erathostenes algorithm (I have linked the C version).

For one thing, this line:
for(i = 2; i <= N; i++){
Starts at i=2, then goes to:
i=3
i=4
i=5
i=6
i=7
Why are you checking values like 4, 6, and 8?You can skip those immediately!
Change your line to:
for(i = 3; i <= N; i+=2){ /* Start at 3, then 5, 7, 9, 11, etc. */

Don't use the modulus operation. Use the sieve.
static unsigned char sieve[10000000] = {0};
long countprimes(long N)
{
long answer = 0;
long i;
long j = 2;
long rootN = ceil(sqrt(N));
while(j < rootN)
{
for(i=j+j;i<N;i+=j)
sieve[i] = 1;
j++;
while(sieve[j])
j++;
}
for(i=2;i<N;i++)
if(!sieve[i])
answer++;
return answer;
}

Related

Need opinions to optimize my code for sorting and find minimum number of K occurences [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 months ago.
Improve this question
int temp = 0;
int counter;
int match = 0;
int FindDup(int array[], int K, int N)
{
// Sorting the array from small big numbers.
for (int i = 0; i < N; i++)
{
for (int j = i + 1; j < N; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
// Find minimum number of K occurences
for (int i = 0; i < N; i++)
{
counter = 0;
for (int j = 0; j < N; j++)
{
if (array[i] == array[j]) // checks if array element is equal
{
counter++;
}
}
if (counter == K)
{
match = array[i];
return match;
}
}
return -1;
}
Info about this function:
This function is a mix of sorting and finding minimum occurrences of an array.
Problem:
The function does work as intended but needs optimization from another user for further improvements of the code. It would be great seeing someones opinions of what would be better and what could be changed.
Input:
arraySize: 10
arrayElements: 2 4 6 7 3 4 5 6 3 6
numberOfOccurrences: 2
Output:
3
since the input is just integer array and there is ain't no difference between saying there is 2 and another 2 as they all the same , you could go up with a hashing techniques , there is a lot of hashing techniques out there , just for a little demonstration , assume that the range of the numbers entered is so small , like from 0 -> 45 and all is positive , then you can use hashing . but if there is negative numbers then you have to use other techniques , if the array is like 0 1 2 5 3000 then this will create array of size 3001 if you used direct hashing techniques , but to solve this problem , there is other hashing techniques that could help you.
for example , you could do something like this :
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[8] = {1, 10, 5, 5, 10, 4, 8, 11};
int max = arr[0];
/*get the maximum element in the array*/
for(int i = 1; i < 8; i++)
{
if(arr[i] > max)
max = arr[i];
}
/*create another variable of size = (max of arr) + 1 and initialized with zeros*/
int *hashTable = (int*) calloc((max + 1), sizeof(int));
/*hashing all the elements*/
for (int i = 0; i < 8; ++i) {
hashTable[arr[i]]++;
}
/*printing the sorted array*/
for (int i = 0; i < (max+1);) {
if(hashTable[i] > 0)
{
printf("%d\t", i);
hashTable[i]--;
}
else
{
i++;
}
}
return 0;
}
and this is the output:
1 4 5 5 8 10 10 11
here , using hashing , you can know the number of occurrence of each element and sort the array in time complexity O(N) .
so simply , read about hashing techniques . that could help answering your question

how to list all pairs of sexy primes

How can i write a program that lists all sexy prime pairs that exist in n numbers.
For example if n = 10 the output should be (5, 11) and (7, 13)
My idea was to generate all primes within n and then add 6 to each and check if the i + 6 is a prime. But it doesnt work, there's no output and the program ends.
#include <stdio.h>
int main() {
int i, j, n, k, isprime = 1, prime2, flag = 0;
scanf("%d", &n);
for (i = 3; i <= n; i++){
for (j = 2; j <= i; j++){
if (i % j == 0)
break;
}
if (i == j){
prime2 = i + 6;
for (k = 3; k <= prime2; k++){
if (prime2 % k == 0){
flag++;
break;
}
}
if (flag == 0){
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Any ideas of what im doing wrong or any tips on how to solve it? (with loops only)
As there're a lot of resources about finding a prime number, I'm not going to discuss that. Rather I'll try to point out the bug in your code.
First problem:
for (k = 3; k <= prime2; k++)
Here you need to run the loop till prime2 - 1. Also you should start checking from 2 rather than 3, just like you did previously. That means,
for (k = 2; k < prime2; k++)
or
for (k = 2; k <= prime2 - 1; k++)
Reason: when k = prime2, prime2 % k will be 0. For finding out whether a number is prime we don't need to check if that number is divisible by 1 and that number itself.
Note: Now you might think why the first prime number loop for (j = 2; j <= i; j++) is working .
It's working because you've given an additional condition if (i == j) after it.
Second problem:
You need to declare the flag variable within the first loop.
for (i = 2; i <= n; i++)
{
int flag = 0;
.... (rest of the code)
....
}
Reason: Basically with the flag value, you're trying to find out whether prime2 is a prime number.
Every time you'll get a prime number from the first loop, you'll have a new value of prime2. In your code, once you're incrementing the value of flag, you're never resetting the flag value.
That's why once your code detects a prime2 which is not a prime, it'll never detect the second prime number again (prime2 which is actually prime).
Overall code:
#include <stdio.h>
int main()
{
int i, j, n, k, isprime = 1, prime2;
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
int flag = 0; // changing point
for (j = 2; j <= i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
prime2 = i + 6;
for (k = 2; k < prime2; k++) // changing point
{
if (prime2 % k == 0)
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Few resources to know more about finding out prime numbers:
Prime Numbers
C Program to Check Whether a Number is Prime or not
Sieve of Eratosthenes
You can use Sieve to speed up the program. It can generate all pairs in O(N log N) time. Here's the Algorithm.
Now, you have a boolean array, is_prime where is_prime[i] is true if i is a prime, false otherwise.
Now, iterate from i = 1 to i = N and check if is_prime[i] && is_prime[i + 6], if the condition is true, output the pair.

Problem Explanation & Bug Detection (Suppose I want to print prime numbers between 3-8 ) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
#include<stdio.h>
int main() {
int i, j, c;
for (i = 3; i <= 8; i++) {
for (j = i + 1; j < 8; j++)
if (i % j != 0) {
}
}
for (i = 3; i <= 8; i++) {
for (j = i + 1; j < 8; j++) {
printf("%d\n", i);
}
}
return 0;
}
I assume that 1st i will be 3 and j will check it can be divided by j until 8 . I know I am talking about wrong things may be it is quite illogical. But I am stucks. Please explain.
Maybe this is what you want.
#include<stdio.h>
int main() {
int i, j, c;
for (i = 3; i <= 8; i++) {
bool prime = true;
for (j = 2; j < i-1; j++)
if (i % j == 0)
prime = false;
if (prime)printf("%d\n", i);
}
return 0;
}
Explanation:
The i-loop checks the numbers from 3 to 8.
The j-loop should run numbers from 2 to i and check if any of those numbers is a factor of i. If so then i is not a prime number.
Problems in your algorithm:
You have got the i-loop correct. But your j-loop is running in vain.
You should check if j is a factor of i in order to determine if i is not a prime number. So you should change that if-statement to if (i % j == 0). You should also have a flag to store this information.
Solution:
// Flag to check if i is a prime number
int isPrime;
// Run numbers from 3 to 8
for (i = 3; i <= 8; ++i)
{
// Let us assume that i is prime
isPrime = 1;
// Check if i is divisible by any number other than 1 and i
for (j = 2; j < i; ++j)
{
// If j is a factor of i then i is not a prime number
if (i % j == 0)
{
isPrime = 0;
break;
}
}
// Print i if it is prime
if (isPrime)
{
printf("\n%d", i);
}
}
Bonus:
Mathematically, it is enough to iterate j from 2 to sqrt(i). It is not necessary here because these are small numbers.

Second least occurring element in an array in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am currently working on a project and for one of the parts I need to determine the second least occurring element in a C array. In any case, the maximum number of elements in the array is going to be 100. I have a function written already to find the least occurring element:
int minRepeat(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 100;
int minNum = 0;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum){
minimum = m;
minNum = arr[j];
}
}
return minNum;
}
arr[] is the inputted array and int i is the size of that array.
I am trying to create a function that will find the second least occurring element in a C array. The function is currently:
int secMin(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 0;
int minNum = 0;
int q = 0;
int k = minRepeat(arr, i);
for(q = 0; q < i; q++){
if(arr[q] == k){
minimum++;
}
}
int minimum2 = 100;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum2){
if(m > minimum){
minimum2 = m;
minNum = arr[j];
}
}
}
return minNum;
}
I am calling the first function to find the least occurring element. Looping through that to see how many times that element occurs in the array, and then doing the same as the first function to find the least occurring, but compare it to the first least element at the end to make sure that this element is the second least occurring.
When arr[] = {1, 1, 1, 2, 2, 3, 2, 2, 4, 1}
I get the least occurring number to be 3 and the second least occurring to be 1.
Sometimes the function works with other input and sometimes it does not, such as in the case above.
Thank you for your help!
Just adjust your first example a little to also store the second least element:
if(m < minimum){
secondminimum = minimum;
secondminNum = minNum
minimum = m;
minNum = arr[j];
}
Edit: I just realised that will only work if least and seconleast element do not have the same number of appearances, but you can capture that case.

C : Input interval and then out only even numbers (2,4,6,8...) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I need some program who after interval input show only even numbers and then all these number multiplying and to screen shows result.
For example,
Input 2 and 7
Output 2 4 6
And 2*4*6
End Result = 48
About the code ,this is all what I have. I dont know with what to begin. Im new in C language :(
int m, n;
n = 0;
m = 0;
clrscr();
printf("Write first number");
scanf("%d", &m);
printf("Write second number");
scanf("%d", &n);
if(n <=0 || m <= 0 || n < m || n==m){
printf("ERROR");
}
Thank you for help! :)
int i = m;
int result = 1;
if (i%2 != 0) i++; // increase start by one when it's not even
for(; i <= n; i += 2) { // increment i by 2 after every loop
result *= i;
}
printf("%d", result);
something like this would be easier to read for beginners i guess:
int i;
int result = 1;
for(i = m; i <= n; i++) {
if(i%2 == 0) {
result *= i;
}
}
printf("%d", result);
You can achieve that with a for-loop :
for (i = m; i < n; i += 2)
end_result *= i;
To check if a number is even you can use the % operator.
if (i % 2 == 0)
Something like :
#include <stdio.h>
int main(void) {
int m = 1, n = 7, end_result = 1, i = 0;
if (m % 2 != 0)
m++;
for (i = m; i <= n; i += 2) {
printf("%d ", i);
end_result *= i;
}
printf("\nThe result is %d\n\n", end_result);
return 0;
}
Output:
2 4 6
The result is 48
What you need to complete this task is "for" loop inside of which you will have an if statement that will check for parity. An integer x is even when dividing modulo by 2 results with 0. You can get modulo in C by using % operator.
if (x % 2 == 0) {
// x is even
}

Resources