钻石由C ++中的数字组成,只使用递归?

时间:2014-10-11 03:43:54

标签: c++ recursion

我目前有代码显示数字三角形:

#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;
}

如果输入为2,则此处显示输出。

  1
1 2 1

这只是我想要的一半。我想制作一个完整的钻石,所以我想要一个“1”作为这个输出的第三行。 RowNumbers函数生成每一行,PrintRhombus函数负责创建数字三角形。我只想使用递归来创建三角形的下半部分。那么我应该创建另一个创建钻石下半部分的递归函数吗?或者我应该在PrintRhombus函数的基础上构建,并在值达到1时启动其他函数。

所以再次我的目标是创建一个数字菱形,所以如果你输入3,那么输出是:

    1
  1 2 1
1 2 3 2 1
  1 2 1
    1      

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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,这样您就不会打印中间行两次,因此中间行之后的行会正确缩进。

答案 2 :(得分: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);
}

只需添加必要的空格

答案 3 :(得分: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; }