代码
#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