程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 代碼意識流——花朵數問題(二)

代碼意識流——花朵數問題(二)

編輯:關於C語言

本文前一部分的鏈接
html">http://www.BkJia.com/kf/201105/92329.html

5.准備寫qiongju()函數
 
  因為要解決的問題對時間的要求以及計算對象是21位數,所以不難想象這個函數可能比較復雜。不可能一蹴而就,所以在編寫前首先要考慮測試。
  在測試用main()內添加函數調用qiongju();

#ifdef CESHI               //測試

   int main( void )
   {
      qiongju();
      system("PAUSE");
      return 0;
   }

#endif //CESHI

   把 0_問題.h 中的 #define QIUJIE 中的 QIUJIE 改成CESHI 編譯運行通過 。這表明文件包含及qiongju()函數原型等方面均沒什麼問題。
   下面轉到 2_窮舉.c 源文件中,填充那個空著的qiongju()函數定義

6.對窮舉方案的思考
  
    最容易想到的窮舉方案是

    方案1.

    for(W_ws=最小W位數;W_ws<=最大W位數;W_ws++)
      {
         //驗算
      }

    這種方案首先需要解決W位數的表示問題,即設計存儲這種數據的數據類型的問題。
    此外還需要考慮這種數據如何賦值、加1及比較大小等問題。
    最主要的,還需要解決解的搜索空間過大的問題。
    一下子同時解決這幾個問題總是讓人有些生畏(但也並非不能解決),因此暫不考慮。


   第二種方案用循環嵌套的方式進行窮舉
   方案2.

   for(第1位數=1;第1位數<JINZHI;第1位數++)
     for(第2位數=0;第2位數<JINZHI;第2位數++)
        ……
       for(第W位數=0;第W位數<JINZHI;第W位數++)
       {
            //驗算
       }

   這種方案在一開始不必考慮W位數的表示問題,但解的搜索空間依然很大。
   解空間巨大的原因是窮舉給出的是各位數的排列,這是一個相當巨大的數目 ((JINZHI-1)*JINZHI^(W-1),對21位十進制數來說,這個值是9*10^20)。然而各種排列中有相當一部分,其各位數N次方的和是相同的(以3位數為例,110和101各位數的3次方之和都為2),不應該重復計算這些值。
   為了避免重復計算這些值,應該只驗算各位數字的各種組合而不是對各位數字的排列進行驗算。為此,可將窮舉的循環結構改良為

   方案2-1.
   for(第1位數=JINZHI-1;第1位數>0;第1位數--)
      for(第2位數=第1位數;第2位數>=0;第2位數--)
         ……
        for(第W位數=第W-1位數;第W位數>=0;第W位數--)
        {
           //驗算
        }         
    這個結構由於保證了各位數字均不大於前面的各位數字,所以得到的是W位數的各種組合。解的搜索空間大大降低(對21位十進制數,只有14307149(30!/9!/21!-1)種可能)。
    這種方案比較形象直觀,容易理解。 

    收工。
    收獲:完成了qiongju()的測試准備。
    感想:寫代碼是簡單的,想代碼應該怎麼寫是困難的。用完成代碼的行數來衡量程序員的工作量是愚蠢的。至於博客園把隨筆移出首頁所依據的標准呢?我想恐怕至少也是見仁見智的吧

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved