有这么一颗树,按照一定的规则进行成长:
1) F : 表示在原来的方向的基础上水平生长,即在原来的方向的基础上画一横
2) + : 增加45度
3) - : 减小45度
4) [ : 记录该节点末的当前状态,下次变化从该节点末开始(相当于压入堆栈push操作)
5) ] : 从上次记录的节点末恢复操作(相当于出栈操作pop)
一棵树的原始形状如下:
F[+F]F[-F]F
第一次生长以后变为:
F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F
第二次生长以后变为:
F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F[+F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F]F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F]F[+F]F[-F]F[+F[+F]F[-F]F]F[+F]F[-F]F[-F[+F]F[-F]F]F[+F]F[-F]F
下图是根据上面给定的字符串生成的图形:
要求输入如下:
N //生长树繁殖的次数, N的范围: 1 <= N <=10
F[+F]F[-F]F //生长树原始的样子,就其实暗含生成规则,要求原始的样子不能超过100个字符
要求输出:
生长树在原始字符串的基础上,经过N次生长后的样子,打印其字符串
这题看起来好复杂,其实稍加分析一下,问题就明朗化了,下面请看分析:
首先根据给定的字符串顺序和成长规则,画出原始图,这里我把他放大了,而且它是按照A->B->C->D->E的顺序进行成长的
经过第一次成长之后,其实是将原来形状按照生长规则,在原来的每个分支上繁殖,这里的分支指的就是A,B,C,D,E几个点:
其实A,B,C,D,E几个点的实质就是生长规则
仔细看下上面的图,其实很容易看出来,就是用原始形状替换原来的A,B,C,D,E几个分支,这样就形成了第一次生长。
同理,第二次生长,其实就是在第一次生长的基础上,用第一次生成好的图,再去替换A,B,C,D,E,这样就可以得到第二次生长以后的图。
问题分析到了这里,其实已经可以看出端倪来了。其实可以不用管成长规则:+,-,[,]
下面还是有2中方法去解体:
方法1:
第一次成长,轮询原始的字符串,找到字符'F'的地方,就用原来字符串去替换,如果不是'F',就不理会
第二次成长,以第一次成长好的字符串为基础,再次轮询,找到'F'的地方,就用原始字符串去替换,如果不是'F',就不理会
依此类推,直到N次成长结束。
下面给出详细的代码,请参考:
- #include <iostream>
#include <string>
#include <string.h> - using namespace std;
- //把最终的结果result按引用传递进来,seed表示原始的字符串,seedLength代表原始字符串的长度
- void replace(string& result, const char* seed, const int seedLength)
- {
- //把每次result的结果复制到一个临时的symbol字符串中,result会根据第i次生长后,产生不同的字符串
- char* symbol = NULL;
- int symbolLen = result.length();
- symbol = new char[symbolLen + 1];
- memset(symbol, 0x00, symbolLen+ 1 );
- strcpy(symbol,result.c_str());
- //在symbol中找字符"F"
- symbol = strstr(symbol, "F");
- //如果在symbol找到了"F",则进行插入替换
- while( NULL != symbol)
- {
- char* tmp = NULL;
- int tmpLen = strlen(result.c_str());
- //这里应该多分配一个字符,应该有个+1,但是仔细考虑一下,是替换操作,"F"本身就占了一个字符,所以就不加1了
- tmp = new char[tmpLen + seedLength];
- //分配一个tmp临时字符指针,并且初始化
- memset(tmp, 0x00, tmpLen + seedLength);
- //下面的三步要合起来理解,就是找到一个"F"以后,用种子去替换这个"F"
- strncpy(tmp, result.c_str(), tmpLen - strlen(symbol));
- strncat(tmp, seed, seedLength);
- strncat(tmp, symbol + 1, strlen(symbol) - 1);
- //把这次的替换赋值给最终的结果
- result.assign(tmp);
- delete[] tmp; //不要忘记delete,防止内存泄漏
- //替换完以后指针自加1,指向下一个字符
- symbol = symbol + 1;
- //从当前字符开始的位置再次寻找"F",找不到就返回NULL;找到就返回以"F"开头的新的字符串
- symbol = strstr(symbol, "F");
- }
- delete[] symbol; //不要忘记delete,防止内存泄漏
- }
- int main(int argc, char** argv)
- {
- char input[100];
- int count, i;
- int seedLength;
- cin >> count;
- cin >> input;
- string Answer;
- const char* seed = input;
- seedLength = strlen(seed);
- //循环N次,也即成长N次
- for(i=0;i<count;i++)
- {
- //i为0的时候设下一个种子,就是原始字符串(成长规则)
- if(0 == i)
- {
- Answer.assign(seed);
- }
- else
- {
- replace(Answer, seed, seedLength);
- }
- }
- cout << Answer << endl;
- return 0;
- }
方法2:再次考虑递归调用
最后一次生成的结果,是前一次生成的结果替换上成长规则,就是例题中的A,B,C,D,E几个点;
一直递归到N等于1的时候,这时就是开始输入的成长规则。
- #include <iostream>
- #include <string>
- #include <cstdio>
- using namespace std;
- string Answer;
- string str;
- int len;
- void replace(int n)
- {
- if(n == 1)
- {
- Answer += str;
- return;
- }
- int i;
- for(i = 0; i < len; i++)
- {
- if(str[i] == 'F')
- {
- replace(n-1);
- }
- else
- {
- Answer += str[i];
- }
- }
- }
- int main()
- {
- int n;
- cin >> n;
- cin >> str;
- len = str.length();
- Answer = "";
- replace(n);
- cout << Answer << endl;
- return 0;
- }
4
F-F++F-F
结果为:
F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F-F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F
3
F+F--F+F
结果为:
F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F
3
F[-F+[F-F]]
结果为: