2014-10-11 30 views
0

我現在有一個顯示數三角形代碼:鑽石由C++中的數字使用遞歸?

#include <iostream> 
using namespace std; 

void RowNumbers(int n, int max) { 
    if (n < max) { 
     cout << n << ' '; 
     RowNumbers(n + 1, max); 
    } 
    cout << n << ' '; 
} 

void PrintRhombus(int n, int space = 0) { 
    if (n > 1) { 
     PrintRhombus(n - 1, space + 2); 
    } 
    cout << string(space, ' '); 
    RowNumbers(1, n); 
    cout << "\n"; 
} 

int main() { 
    int a; 
    cout << "Enter a number [1-9]: " << endl; 
    cin >> a; 
    if (a > 0 && a < 10) { 
     PrintRhombus(a, 0); 
    } 
    else 
     cout << "Wrong input." << endl; 
} 

輸出在此顯示,如果輸入是二。

1 
1 2 1 

這只是我想要的一半。我想做一個完整的鑽石,所以我想要一個「1」作爲這個輸出的第三行。 RowNumbers函數生成每一行,PrintRhombus函數負責創建數字三角形。我只想使用遞歸創建三角形的下半部分。那麼我應該創建另一個創建鑽石下半部分的遞歸函數嗎?或者我應該建立在PrintRhombus函數上,並在值達到1時啓動其他內容。

所以再次我的目標是要打造一批鑽石,因此,如果您輸入3,那麼輸出是:

1 
    1 2 1 
1 2 3 2 1 
    1 2 1 
    1  
+0

有什麼特別的爲什麼這需要用遞歸來完成?如果解除這個限制,可以創建一個更簡單,更易讀的程序。 – 2014-10-11 03:55:59

+0

我知道有一種方法可以做到這一點沒有遞歸,但這是一個家庭作業的任務,並且我只限於使用遞歸... – edboysega321 2014-10-11 03:59:44

+0

Nitpick:請[不要空間/格式化你的代碼](http ://stackoverflow.com/revisions/26310838/1)(編輯)。格式確實涉及很多主觀性,這是事實......是否把支撐放在下一行/等。但是,像這樣大量的流浪線不是你在練習中看到的...有充分的理由。它的個人選擇方面確實結束在這裏的Q&A中引發實際問題,因爲它會在代碼摘錄中產生不必要的滾動條,並且您無法在一個頁面上看到所有內容。 – HostileFork 2014-10-11 05:09:45

回答

1

這裏是我會做:

首先,在一個循環的形式寫PrintRhombus

void PrintRhombus(int n) { 
    for(int i = 1; i < 2 * n; i++){ 
     int numbers_in_line = i < n ? i : 2 * n - i; 
     int space = (n - numbers_in_line) * 2; 
     cout << string(space, ' '); 
     RowNumbers(1, numbers_in_line); 
     cout << endl; 
    } 
} 

測試你的循環,並確保你得到它的權利。關於循環的推理通常比遞歸函數容易得多。

現在將該循環轉換爲尾遞歸函數。這種轉換是微不足道的:

void PrintRhombus(int n, int i = 1){ 
         //^loop variable --> extra parameter 
    if(i == 2 * n) return; // <- terminating condition --> return 

    // loop body remains unchanged 
    int numbers_in_line = i < n ? i : 2 * n - i; 
    int space = (n - numbers_in_line) * 2; 
    cout << string(space, ' '); 
    RowNumbers(1, numbers_in_line); 
    cout << endl; 

    // Now do recursive call with incremented loop variable 
    PrintRhombus(n, i+1); 
} 

Demo

0

這是因爲你只迭代,以菱形頂部,然後打印出上半場。我找不到那個只使用一個功能的解決方案,但這裏有兩個功能,一個是頂部,一個在底部,這項工作:

void PrintRhombusTop(int n, int space = 0) 
{ 
    if (n > 1) 
    { 
     PrintRhombusTop(n - 1, space + 2); 
    } 
    cout << string(space, ' '); 
    RowNumbers(1, n); 
    cout << "\n"; 
} 

void PrintRhombusBottom(int n, int space) 
{ 
    if (n >= 1) 
    { 
     cout << string(space, ' '); 
     RowNumbers(1, n); 
     cout << "\n"; 
     PrintRhombusBottom(n - 1, space + 2); 
    } 
} 

叫他們main這樣的:

if (a > 0 && a < 10) 
{ 
    PrintRhombusTop(a, 0); 
    PrintRhombusBottom(a - 1, 2); 
} 

您需要將(a - 1, 2)更改爲PrintRhombusBottom,這樣您纔不會打印中間行兩次,因此中間行之後的行可以正確縮進。

+0

對不起,首先發布不完整的答案,我意外地連續擊中了「Tab」和「Enter」。 – Hosch250 2014-10-11 04:20:05

+0

等一下,輸入'1'時出錯。 – Hosch250 2014-10-11 04:23:48

+0

好,已修復並經過測試。 – Hosch250 2014-10-11 04:27:08

0

遵循同樣的邏輯RowNumber,你可能希望這樣的事情:

void PrintRhombus(int min, int max) 
{ 
    if (min < max) 
    { 
     RowNumber(1, min); 
     PrintRhombus(min+1, max); 
     RowNumber(1, min); 
    } 
    else 
     RowNumber(1, max); 
} 

只需添加必要的空間

0

另外一個樂趣:

#include <iostream> 
#include <string> 

void row(int n, int m) { 
    std::cout << n << " "; 
    if (n < m) { 
    row(n + 1, m); 
    std::cout << n << " "; } } 

void line(int n, int r, int m) { 
    std::cout << std::string(2 * (m - n), ' '); 
    row(1, r); 
    std::cout << "\n"; } 

void diamond(int n, int r, int m) { 
    line(n, r, m); 
    if (r < m) { 
    diamond(n + 1, r + 1, m); 
    line(n, r, m); } } 

int main(int, char* []) { 
    std::cout << "Number? "; 
    int n = 0; 
    std::cin >> n; 
    diamond(1, 1, n); 
    return 0; }