C4GPLT_L1-002_打印沙漏

文章目录


代码

#include <stdio.h>

typedef struct PrintData{
    int SymbolLine;
    int LineNum;
}PrintInfo;

PrintInfo AnalyseInfo(PrintInfo);
void PrintFigure(int, char);
void PrintLine(int, int, char);

int main()
{
    char Symbol;
    PrintInfo Info;
    scanf("%d %c", &Info.SymbolLine, &Symbol);

    Info.LineNum = 0;

    PrintFigure(AnalyseInfo(Info).LineNum, Symbol);
    printf("%d", AnalyseInfo(Info).SymbolLine);

    return 0;
}

/*Before printing the figure, we should first calculate how many lines can those symbols contain.*/
PrintInfo AnalyseInfo(PrintInfo Info)
{
  int SubNum = (Info.LineNum == 0) ? 0 : ((Info.LineNum * 2 - 1) * ((Info.LineNum == 1) ? 1 : 2));

  Info.SymbolLine -= SubNum;

  if(Info.SymbolLine >= ((Info.LineNum * 2 + 1) * ((Info.LineNum+1 == 1) ? 1 : 2))){
      Info.LineNum++;
      return AnalyseInfo(Info);
  }
  else{
      Info.LineNum = (Info.LineNum - 1 ) * 2 + 1;

      return Info;
  }
}

/*Print figure by line number and symbol*/
void PrintFigure(int LineNum, char Symbol)
{
    int i, SymbolNum;

    for(i=0; i< LineNum; i++)
    {
        SymbolNum = (i < LineNum/2) ? (((LineNum+1)/2-(i+1))*2+1): (((i+1)-(LineNum+1)/2)*2+1);
        PrintLine(LineNum, SymbolNum, Symbol);
        printf("\n");
    }

    return;
}

/*Print each line of the figure by line length, symbol number and symbol*/
void PrintLine(int LineLen, int SymbolNum, char Symbol)
{
    int i;

    for(i=0; i<(LineLen-SymbolNum)/2; i++)
    {
        printf(" ");
    }

    for(i=0; i<SymbolNum; i++)
    {
        printf("%c", Symbol);
    }

    return;
}


思路

这个问题一共分为两部分:一是计算出沙漏的总行数进而也就可以得到剩余的符号数,二是根据沙漏总行数打印图形。
对第一个问题:通过函数AnalyseInfo的递归调用可以解决,在每一次调用中,总符号数减去前回行数消耗的符号数,然后再与下一回行数所需的符号数进行比较。
对第二个问题则分成两个函数:PrintFigure逐行打印符号,PrintLine则根据沙漏的总行数、符号数和符号打印每一行的具体内容。


总结

在这个问题中使用了两个知识点:一是尾递归,二是返回值为结构体类型的函数。

尾递归
尾递归相对于一般的递归方法占用的存储空间更少。这是由于每一次调用函数的返回值已经以参数的形式传入到下一回函数调用中,因此至多占用2回函数调用的存储空间。

结构体
在C语言中,结构体非常有效的解决了数据的聚合问题,将有关联的数据可以绑定在一起。在以前的认识中,有一个误区,就是函数的返回值类型只能是一般类型,如果要使用结构体类型则需要通过指针来实现,实验的结果是,这种认识是错误的。不仅可以直接返回结构体,并且可以直接使用“.”操作符来取值。

最后,照例我还是要吹嘘一把的,来一发洋文的递归例句,来自Simon Smith的“Jerusalem: The biography”。

The sanctuary of the earth is Syria; the sanctuary of Syria is Palestine; the sanctuary of Palestine is Jerusalem; the sanctuary of Jerusalem is the mountain; the sanctuary of the Mountain is the place of worship; the sanctuary of the place of worship is the Dome of the Rock.
by Thaur ibn Yazid, Fadail

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值