簡體   English   中英

如何計算遞歸函數的調用(遞增1) C ++

[英]How to count the calls of a recursive function (Increment by 1) | C++

我有以下代碼如下。 它接受輸入並逐行打印以解決河內問題。 我要做的就是在每一行中依次打印step1,step2等,從1到步驟結束,如下例所示:


輸入磁盤數:3
步驟1:1-> 2將一個磁盤從原始釘移到另一個釘
步驟2:1-> 3將一個磁盤從原始釘移到目標釘
步驟3:2-> 3將一個磁盤從附加釘移到目標釘

  #include <iostream>
int count=1;
     void ToH(int dskToMv, int cLocation, string orpeg, int tmpLocation, string expeg, int fLocation, string depeg)
    {
         if( dskToMv != 0 ) 
        {
count++;
            ToH( dskToMv-1, cLocation, orpeg, fLocation, depeg, tmpLocation, expeg);
            cout<<"Step "<<count<<": Move one disk from the "<< orpeg << " to the " << depeg
                << " " << cLocation << " -> " << fLocation << endl;
            ToH( dskToMv-1, tmpLocation, expeg, cLocation, orpeg, fLocation, depeg);
        }
    }

    int main()
    {
        int c;
        cout << "Enter the number of disks: ";
        cin >> c;
        ToH(c, 1, "original peg ", 2, "extra peg", 3, "destination peg");
    }

在遞歸中,當您需要每次迭代“跟蹤”某些內容時,有幾種方法:

  1. 原始全局變量-這些僅允許保留單個狀態。 如果遞歸分支等,則可能無法正常工作,因為一個分支將覆蓋另一個分支正在使用的值。 對於簡單地存儲諸如計數之類的東西,這些趨向於很好地工作。

  2. 將參數傳遞給函數-函數的參數存儲在堆棧中。 調用函數時,它們會被推送,因此對於每次遞歸,每次迭代調用都會以“堆棧”形式存儲參數值。 這與遞歸效果很好,因為不同的分支不會破壞其他值(彈出發生在函數調用的末尾,而僅彈出調用推入的值)。

  3. 使用復雜的全局數據結構。 它們本質上將參數存儲在函數調用之外,並允許發生更復雜的事情(例如,使用隊列而不是堆棧),但需要更多工作。 因為它們在功能外部,所以如果需要,可以由其他分支查看。

您需要做的就是聲明一個全局int,然后在函數調用中對其進行遞增。 每次調用函數時,該值都會增加,因此會計算函數調用的次數。 因為它只是遞增的,所以分支沒有問題(因為每個分支都會做同樣的事情,因此無法區分)。

int count = 0;
 void ToH(int dskToMv, int cLocation, string orpeg, int tmpLocation, string expeg, int fLocation, string depeg)
{
   count++;
     if( dskToMv != 0 ) 
    {
        ToH( dskToMv-1, cLocation, orpeg, fLocation, depeg, tmpLocation, expeg);
        cout<<" Move one disk from the "<< orpeg << " to the " << depeg
            << " " << cLocation << " -> " << fLocation << " - " << count << endl;
        ToH( dskToMv-1, tmpLocation, expeg, cLocation, orpeg, fLocation, depeg);
    }
}

另外,如果您希望允許回溯並因此實際計算“級別”,則可以使用一個參數:

 void ToH(int dskToMv, int cLocation, string orpeg, int tmpLocation, string expeg, int fLocation, string depeg, int count = 0)
{
     if( dskToMv != 0 ) 
    {
        ToH( dskToMv-1, cLocation, orpeg, fLocation, depeg, tmpLocation, expeg, count + 1);
        cout<<" Move one disk from the "<< orpeg << " to the " << depeg
            << " " << cLocation << " -> " << fLocation << " - " << count << endl;
        ToH( dskToMv-1, tmpLocation, expeg, cLocation, orpeg, fLocation, depeg, count + 1);
    }
}

並非所有方法都相同。 當您學習將遞歸視為對大型分支數據結構的一種“搜索”時,考慮這些事情就容易多了。 當您僅使用與迭代等效的簡單遞歸時,這些不同的方法之間沒有太多區別。

您可以嘗試使用靜態變量。 每次(遞歸)調用該函數時,請遞增此變量。

#include <iostream>

 void ToH(int dskToMv, int cLocation, string orpeg, int tmpLocation, string expeg, int fLocation, string depeg)
{
    static int count=0 
    if( dskToMv != 0 ) 
    {
        count++;
        ToH( dskToMv-1, cLocation, orpeg, fLocation, depeg, tmpLocation, expeg);
        cout<<"Step "<<count<<": Move one disk from the "<< orpeg << " to the " << depeg
            << " " << cLocation << " -> " << fLocation << endl;
        ToH( dskToMv-1, tmpLocation, expeg, cLocation, orpeg, fLocation, depeg);
    }
}

int main()
{
    int c;
    cout << "Enter the number of disks: ";
    cin >> c;
    ToH(c, 1, "original peg ", 2, "extra peg", 3, "destination peg");
}

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM