文章出處

一、前言

老師給出的要求:

閱讀下面程序,請回答如下問題:

問題1:這個程序要找的是符合什么條件的數?

問題2:這樣的數存在么?符合這一條件的最小的數是什么?

問題3:在電腦上運行這一程序,你估計多長時間才能輸出第一個結果?時間精確到分鐘(電腦:單核CPU 4.0G Hz,內存和硬盤等資源充足)。

問題4:在多核電腦上如何提高這一程序的運行效率?

(注:該程序、用C#語言編寫,但是只要有C語言基礎完全沒有閱讀壓力,如果對部分語句不懂請自行查詢)

using System;

using System.Collections.Generic;

using System.Text;

namespace FindTheNumber

{
  class Program
  {
    static void Main(string[] args)
    {
int [] rg ={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
      for (Int64 i = 1; i < Int64.MaxValue; i++)
      {
        int hit = 0;
        int hit1 = -1;
        int hit2 = -1;
        for (int j = 0; (j < rg.Length) && (hit <=2) ; j++)
        {
          if ((i % rg[j]) != 0)
          {
            hit++;
            if (hit == 1)
            {
              hit1 = j;
            }
            else if (hit == 2)
            {
              hit2 = j;
            }
            else
              break;
          }

        }
        if ((hit == 2)&& (hit1+1==hit2))
        {
          Console.WriteLine("found {0}", i);
        }
      }
    }
  }
}

二、分析

自己第一次看到這個C#代碼時候,就覺得C#繼承了C及C++語言的特性。首先我看著別扭,我把它寫成了c語言。

Int64相當于2^64次方,10^20次方,相當于10億=10^10次方。

(1)當i=1

j=0     i%rg[0]=1%2=1   1!=0   hit++   hit=1    hit1=j=0;

j=1     i%rg[1]=1%3=1   1!=0   hit++   hit=2    hit1=j=1;

j=2     i%rg[2]=1%4=1   1!=0   hit++   hit=3    break跳出當前循環。判斷是否符合條件,不符合

(2)當i=2

j=0     i%rg[0]=2%2=0   0==0   

j=1     i%rg[1]=2%3=2   2!=0   hit++   hit=1    hit1=j=1;

j=2     i%rg[2]=2%4=2   2!=0   hit++   hit=2    hit2=j=2;

j=3     i%rg[3]=2%5=2   2!=0   hit++   hit=3    break跳出當前循環。判斷是否符合條件,不符合

(3)當i=3

j=0     i%rg[0]=3%2=1   1!=0   hit++   hit=1    hit1=j=0;

j=1     i%rg[1]=3%3=0   0==0   hit++   hit=2    hit2=j=1;

j=2     i%rg[2]=3%4=1   1!=0   hit++   hit=3    break跳出當前循環。判斷是否符合條件,不符合

(4)當i=4

j=0     i%rg[0]=4%2=0   0==0  

j=1     i%rg[1]=4%3=1   1!=0   hit++   hit=1    hit1=j=1;

j=2     i%rg[2]=4%4=0   0==0 

j=3     i%rg[3]=4%5=4   4!=0   hit++   hit=2   hit2=j=3;

j=4     i%rg[3]=4%6=4   4!=0   hit++   hit=3   break跳出當前循環。判斷是否符合條件,不符合

。。。。。。。

。。。。。。。。。

    從這兒看出來:條件是:最終要是hit==2&&hit1+1==hit2;相鄰的兩個數同時取余后!=0,就一定滿足條件hit1+1==hit2

     只有當相鄰的兩個數是在最后出現,break,前面所有的數都能被整除,那么問題來了,相鄰兩個數一定是一個奇數和一個偶數。偶數可以拆分為之前的2*相關的數。也就是說,偶數可以用之前的兩個數來表示。即不存在這樣的數。

三、解答

Int64相當于2^64次方,10^20次方,相當于10億=10^10次方。

問題1:這個程序要找的是符合什么條件的數?

答:這個程序要找的數,相鄰兩個數是質數的數。

問題2:這樣的數存在么?符合這一條件的最小的數是什么?

答:這樣的數不存在。

問題3:在電腦上運行這一程序,你估計多長時間才能輸出第一個結果?時間精確到分鐘(電腦:單核CPU 4.0G Hz,內存和硬盤等資源充足)。(我的電腦是四核,3,4GHz)

答:測試的數據是1億,用時5.034秒。

測試的數據是10億,用時51.160秒。(基本上是滿足增大10倍,時間上也是增大10倍)

 

所以,我們可以考慮認為:當數據達到10^20時,5.034*10^11秒=839 000 0000分鐘。

問題4:在多核電腦上如何提高這一程序的運行效率?

答:多核電腦中,提高每個核的運算效率。實施多線程的控制,把這些數均分到多段,一段一個核,在每一個核中計算每一段的這些數,把每一個核的運算結果輸出,多線程控制輸入,運算,控制。

附帶一張轉換成C語言的代碼(用Codeblock測得時間)

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
     long long i,j;
    int a[]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
    for(i=1;i<1000000000;i++)//1億
    {
        int hit=0;
        int hit1=-1;
        int hit2=-1;
        for(j=0;j<30&&hit<=2;j++)
        {
            if(i%a[j]!=0)
            {
                hit++;
                if(hit==1)
                    hit1=j;
                else if(hit==2)
                    hit2=j;
                else
                    break;

            }
        }
        if(hit==2&&(hit1+1==hit2))
            cout<<i<<endl;
    }
    return 0;
}

四、總結

1、分析問題的方式從簡單到難。

2、從邏輯上進行推理,變換邏輯思維解決問題。

3、自己需要學習的知識還有很多,自己會每天進步一點。

 


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()


    留言列表 留言列表

    發表留言