天天看點

C#程式代碼分析(第三周)

       剛開始看到這段程式,都不知道是什麼東西,問過室友才知道是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);
            }
          }
        }
      }
}      

閱讀程式,回答下列問題:

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

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

問題3:在電腦上運作這一程式,你估計多長時間才能輸出第一個結果?時間精确到分鐘(電腦:單核CPU 4.0G Hz,記憶體和硬碟等資源充足)。

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

解答如下:

      剛開始看這個程式的時候,有一些地方不太懂,這個程式使用C#寫的,是以自己就建立了一個C#控制台應用程式,知道了語句Console.WriteLine是用來做輸出的。利用語句Console.WriteLine("found {0}", Int64.MaxValue);那麼Int64.MaxValue這個數究竟是多大呢?在網上找到了答案(https://msdn.microsoft.com/zh-cn/library/system.int64.maxvalue(v=vs.110).aspx),Int64是有符号 64 位整數資料類型,相當于C++中的long long ,表示值介于 -2^63 ( -9,223,372,036,854,775,808) 到2^63-1(+9,223,372,036,854,775,807 )之間的整數。用于整數值可能超過 int 資料類型支援範圍的情況。那就應該是個很大的數了,在這麼大的範圍為了找幾個數,看來不是很好找。。。

     首先是第一層的for循環,i從1開始,一直到9223372036854775807,每循環一次,i增加一個數,每一次的循環都對hit,hit1,hit2進行指派,分别為0,-1,-1,然後進入第二層for循環,j從0開始,判斷條件是j小于30(即數組的長度)且hit小于等于2,判斷之後如果成立,執行操作:

if ((i % rg[j]) != 0)
          {
            hit++;
            if (hit == 1)
            {
              hit1 = j;
            }
            else if (hit == 2)
            {
              hit2 = j;
            }
            else
              break;
          }      

     然後j加1,然後繼續第二層for循環,直至不滿足條件為止;然後判斷hit是否等于2與hit1+1是否等于hit2的交,如果滿足,那麼輸出i,不滿足繼續第一層for循環,直至i大于等于9223372036854775807為止。

     用VS運作了一下,等了好久沒有等到結果,計算機的性能跟不上的原因吧。試着在C上運作了一下:

     輸出結果的第一列是i,第二列是hit,第三列是hit1,第四列是hit2,第四列是hit2-hit1。 

     (1)hit <= 1時;

C#程式代碼分析(第三周)

     (2)hit <= 2時;

     (3)hit <= 3時;

      (4)hit <= 4時;

    C#上運作了好久都沒出來結果,在C上的嘗試自己電腦的性能實在跟不上,-9,223,372,036,854,775,808 到+9,223,372,036,854,775,807之間找到這樣數,數值範圍太大了。。。。表示放棄計算了,雖然這樣的數是存在的!