I happened to see a program similar to Goldbach's conjecture on CSDN:
C language daily practice - day 52: an even number can always be expressed as the sum of two prime numbers_ Super Hui sir blog CSDN blog C language daily practice November 3, 2021 - Analysis: Although I can't prove this conjecture in C language, I can set a range and prove that the number in the range meets this condition. Idea: three-layer loop: the first layer traverses all even numbers greater than 2 (given range), the second layer traverses the first prime addend, and the third layer traverses the second prime addend. Only when all even numbers have two prime addends (addends of prime numbers) can it be proved that within this number range, an even number can always be expressed as the sum of two prime numbers.https://blog.csdn.net/weixin_43772810/article/details/121129617 I felt it was a little interesting, so I tried to write it myself. Because I hadn't written C language for a long time, I spared a little detour, but I also wrote it, so I sent it out to make a fool of myself. Ignore the code style and write it casually. Tested some data and felt that the performance was OK.
4-1 million even numbers, 41 seconds;
990000 to 1 million, 10000 data, less than 1 second.
Send the result first, and the code is attached.
jie@Jies-MacBook-Pro test1 % ./a.out your input: 4 - 1000000 Program run time: 41373.597 ms jie@Jies-MacBook-Pro test1 % ./a.out your input: 990000 - 1000000 Program run time: 927.436 ms
The algorithm has two ideas:
1. Sharpen the knife without mistaking the firewood cutter
In any case, the calculation of prime numbers should not be repeated. Just run enough at one time and put them there for standby. From the actual situation, the calculation of prime numbers below millions is still very fast;
2. Addition algorithm
The two head approximation algorithm is adopted, min=2, max = the prime number closest to the input number, the larger one and the smaller one do not matter. Take 168 as an example.
The first round: min=2, max=167, the sum is greater than 168, maxIndex-1
Second round: min=2, max=163, sum less than 168, minIndex+1
The third round: min=3, max=163, the sum is less than 168, minIndex+1
The fourth round: min=5, max=163, sum = 168, successful.
In addition, there is room for optimization in theory, because so many calculations are independent and there is no interaction between various numbers. In theory, multi-core computing can be used. If necessary, it can be selected according to the actual scene.
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> typedef int BOOL; #define TRUE 1 #define FALSE 0 #define MAX_PRIME_LENGTH 1000000 long _primes[MAX_PRIME_LENGTH]; void calcPrimes(long max); int isPrime(long x); long findSmallerPrimeIndex(long number); int divideNumber(long number, long* x, long* y); int main() { double start = clock(); long min = 990000; long max = 1000000; printf("your input: %ld - %ld\n", min, max); calcPrimes(max*2); for(long i=min; i<=max; i+=2){ long x=0, y=0; divideNumber(i, &x, &y); //printf("%ld = %ld + % ld\n", i, _primes[x], _primes[y]); } double end = clock(); printf("Program run time:%.3f ms\n",(double)(end-start)/1000); //Print run time return 0; } // Divide a number into the sum of two prime numbers int divideNumber(long number, long* x, long* y){ // Start at both ends, starting with the largest number less than number long maxPrimeIndex = findSmallerPrimeIndex(number); //printf("maxPrimeIndex = %ld\n", maxPrimeIndex); long indexX = 0; long indexY = maxPrimeIndex; // *x to right, * y to left while(indexX < indexY) { //printf("min = %ld, max = %ld\n", _primes[indexX], _primes[indexY]); long r = _primes[indexX] + _primes[indexY]; if(r < number){ indexX++; } else if(r > number){ indexY--; }else{ *x = indexX; *y = indexY; return 0; } } return -1; } // Find the prime number closest to number and less than number (there may be a bug in this place. The found number may not be less than, but may be greater than, but it has little impact on performance) long findSmallerPrimeIndex(long number){ long i=0; for(i=0; _primes[i]<=number; i++); return i; } // Calculates all prime numbers less than max void calcPrimes(long max){ long index = 0; for(long i=0; i<MAX_PRIME_LENGTH; i++){ _primes[i] = 0; } for(long i=2; i<max; i++){ if(isPrime(i) == TRUE){ _primes[index++] = i; } } } // Judge whether it is prime BOOL isPrime(long x){ // As long as it can be_ Divide the contents in primes, even if it fails for(long i=0; _primes[i]<=sqrt(x); i++){ long m = _primes[i]; if(x % m == 0){ return FALSE; } } return TRUE; }