• 更新后的哥德巴赫猜想(位运算)


    德巴赫猜想:一个不小于6的偶数,总能分解成两个质数之和。

    #include(stdio.h)

    #include(math.h)

     

    boolean   isPrime(int  num);

    boolean   isGoldbachConjecture(int  arrange);

     

    boolean   GoldbachConjecture(int  arrange){

         boolean   isGoldbachRight;

         boolean   found;

         int   num;

         int   i;

            for(num = 6,isGoldbachRight =1;isGoldbachRight&&num<=arrange;num+=2){

           //例如:6=3+3;

                     //24=3+(24-3);

                     //24=5+(24-5);

                     //24=7+(24-7);

                    //24=9+(24-9);

            //这是下面这个循环的手工过程。

           for(i=3,found=-1;!found&&i<=num/2;i+=2){

                if(isPrime(i)&&isPrime(num-i)){

                found=1;

                }

    }

          if(!found){

              isGoldbachRight = -1;

              printf("%d ",num);

              }

    }

          return   isGoldbachRight;

    }

    boolean   isPrime(int  num){     //判断是否是质数

          int i;

          int   maxNum = (int)(sqrt(num));

          if(num>2&&num%2 == 0){

             return  -1;

          }

          for(i=3;i<maxNum&&num%i;i+=2){

           }

        return  i>maxNum;

        }

       int main(){

           int  num;

           printf("请输入范围:");

           scanf("%d",&num);

           if(GoldbachConjecture(num)==-1){

             printf("哥德巴赫猜想错了!");

            }esle{

              printf("哥德巴赫猜想从6到%d是正确的 ",num);

            }

          return 0;

          }

    但是这个程序对于7位数以上的数据,会非常耗时!!!

    所以有了更加高效的解决手段:利用数组的位运算解决:

      首先:将相当大的数,全部存储到数组中;或者说,有一个数组,里面有n个数,这n个数就是

    我们要处理的数据;其实,如果定义一个有n个数的数组,那么,其下标就是0到n-1!而其值,我们要求为0或者1,且0表示非质数,1表示质数(相反亦可)例如:数组名numSet.

      0  0  1  1  0  1  0  1  0  0  0

      0  1  2  3  4  5  6  7  8  9  10

    对于上述数组的处理可以这样操作:return numSet[num];

    而对于数组的赋值,可以这样来:int   numSet[1000] = {0};

    #include <stdio.h>
    #include <math.h>
    #include <time.h>
    #include <malloc.h>

    #include "./include/mec.h"

    u8 *set = NULL;                                                            //在宏中定义u8类型为unsigned char(用了宏,为避免错误发生)

    boolean isPrime(int num);
    boolean GoldbachConjecture(int arrange);
    void setPrime(int arrange);

    void setPrime(int arrange) {                                //查找质数
        int i = 3;
        int j;
        int maxNum = (int) sqrt(arrange);
        
        set = (u8 *) calloc(sizeof(u8), (arrange + 7) >> 3);
        
        for (j = 4; j < arrange; j += 2) {
            SET_BYTE(set[j >> 3], j & 7);                                    //置0操作,相当于set[j] = 1;
        }
        while (i <= maxNum) {
            if (0 == GET_BYTE(set[i >> 3], i & 7)) {        //置1操作,相当于if(0 == set[i])
                for (j = i*i; j < arrange; j += (i << 1)) {        //左移n位,相当于原数*2^n,再去掉前面多出来的那些位!所以j += (i << 1)相当于j += i + 2;
                    SET_BYTE(set[j >> 3], j & 7);                        //置0操作,相当于set[j] = 1;
                }
            }
            i += 2;
        }
    }


    boolean GoldbachConjecture(int arrange) {
        boolean isGoldbachRight;
        boolean found;
        int num;
        int i;
        
        for (num = 6, isGoldbachRight = TRUE; isGoldbachRight && num <= arrange; num += 2) {
            for (i = 3, found = FALSE; !found && i <= num/2; i += 2) {
                if (isPrime(i) && isPrime(num-i)) {
                    // printf("%d = %d + %d ", num, i, num-i);
                    found = TRUE;
                }
            }
            if (!found) {
                isGoldbachRight = FALSE;
                printf("%d ", num);
            }
        }
        
        return isGoldbachRight;
    }

    boolean isPrime(int num) {
        return 0 == GET_BYTE(set[num >> 3], num & 7);
    }

    int main() {
        int num;
        boolean ok = TRUE;
        clock_t start;                                      //返回当前进程创建到现在经过的时钟周期数。
        long mid;                                                    ////clock_t   ,long是一样的。
        clock_t end;                                            
        clock_t deltaA;
        long deltaB;

        printf("输入范围:");
        scanf("%d", &num);
        
        start = clock();
        setPrime(num);
        mid = clock();
        ok = GoldbachConjecture(num);
        end = clock();
        deltaA = mid - start;
        deltaB = end - mid;
        printf("%d.%03d, %d.%03d ", (int) (deltaA / 1000000), (int) (deltaA % 1000000 / 1000),
                (int) (deltaB / 1000000), (int) (deltaB % 1000000 / 1000));
        
        if (FALSE == ok) {
            printf("哥德巴赫猜想错了! ");
        } else {
            printf("哥德巴赫猜想在6到%d之间正确 ", num);
        }
        
        free(set);
        
        return 0;
    }


  • 相关阅读:
    Winform中在ZedGraph中最多可以添加多少条曲线(转)
    c#委托的含义和用法
    vs2010打开vs2017工程
    C# Socket编程资源
    C# 调用打印机 打印 Excel (转)
    NPOI 教程
    C# 调用C++ DLL 的类型转换(转载版)(转)
    进程间通信(网络阅读笔记)
    NPOI 第二篇 设置样式与合并单元格(转)
    分布式事务的 6 种解决方案,写得非常好!
  • 原文地址:https://www.cnblogs.com/youdiaodaxue16/p/9122079.html
Copyright © 2020-2023  润新知