题目如上,当时我在做题的时候第一时间没有想到递归而是想到字符串各种库函数的应用,只要在上一列的最后一个位置整出一个字母,再用strncat接上之前的就行了,最后一个位置下标为strlen(当前字符串),当时我就忘记考虑,每进行一行的时候要在最后加上‘\0’,否则最后可能会越界。
初始代码如下:
#include<stdio.h> #include<string.h> int main() { int n,i,j=1,z=0;//j为第一次接长的位置,z为旧位置 char a[100]; a[0]='A'; scanf("%d",&n); if(n==1) { printf("A"); return 0; } for(i=1;i<n;i++) { a[j]=a[z]+1;//j为上一个位置上的字母加1 a[j+1]='\0' ;//要不然strlen就检测不到了 strncat(a,a,strlen(a)-1); z=j;//j的上一个位置 j=strlen(a);//j的新位置 } printf("%s",a); }
但这样依旧有很大缺陷,我是要开辟多少内存的数组呢,显然我这里开辟的100是不能满足输出n=26时候数组的长度的,因此我觉得可以用malloc来做就不浪费内存;
代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> int changdu(int n) { if(n==1) return 1; return 2*changdu(n-1)+1; } int main() { int n,i,j=1,z=0;//j为第一次接长的位置,z为旧位置 scanf("%d",&n); int k=changdu(n); //1,3,7,15由规律知道该分配多少 char *a=(char *)malloc(sizeof(char)*k); a[0]='A'; if(n==1) { printf("A"); return 0; } for(i=1;i<n;i++) { a[j]=a[z]+1;//j为上一个位置上的字母加1 a[j+1]='\0' ;//要不然strlen就检测不到了 strncat(a,a,strlen(a)-1); z=j;//j的上一个位置 j=strlen(a);//j的新位置 } printf("%s",a); free(a); }
但我重新再看这道题的时候,我就有了新的想法如果我要打印某一行的字符串,我只需要打印它上一行的字符串然后再打印一个字符,再打印上一行的字符串即可,但它上一行的内容是什么,我压根不关心,因为那是电脑要做的,我们只需要考虑第一行的情况即可,这是一种递归的思想。
代码如下:
#include<stdio.h> void An(int n) { if(n==1) //用第一行为A作为结束的标志 { printf("A"); return ; } An(n-1);//打印上一行 printf("%c",64+n);//接上一个字符 An(n-1);//打印上一行 } int main() { int n; scanf("%d", &n); int i; An(i); return 0; }