在C++中只使用递归的数字组成的菱形

Diamond made of numbers in C++ using only recursion?

本文关键字:数字 递归 C++      更新时间:2023-10-16

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

#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      

以下是我要做的:

首先,以单个循环的形式写入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);
}

演示。

这是因为您只迭代到菱形的顶部,然后打印出上半部分。我找不到一个只使用一个函数的解决方案,但这里有两个函数,一个用于顶部,另一个用于底部,可以工作:

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,这样就不会打印中间一行两次,这样中间一行之后的行就会正确缩进。

要遵循与RowNumber相同的逻辑,您可能需要这样的东西:

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

只需添加必要的空格

另一个有趣的:

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