给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
第一项是数字 1
描述前一项,这个数是 1 即 “一个 1 ”,记作 11
描述前一项,这个数是 11 即 “两个 1 ” ,记作 21
描述前一项,这个数是 21 即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211 即 “一个 1 一个 2 两个 1 ” ,记作 111221
示例 1:
输入: 1
输出: "1"
解释:这是一个基本样例。
示例 2:
输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。
题解:
这个题其实就是要看懂题目说了什么,解决方法还是挺简单的。
其实无非就是:
2. 11
3. 21
4. 1211
第二行11的前面一个1是用来修饰后面的那个1的
第三行可以理解为2个1,而省略了一个1,实则应为211
第四行可以理解为1211,有1个2,有2个1
其余行同理。
char * countAndSay(int n){
int maxsize = 5000;
char pur*=(char*)malloc(sizeof(char)*maxsize);
char cur*=(char*)malloc(sizeof(char)*maxsize);//设置一个空间来储存增加的元素
pre[0] = '1';
if(n == 1)//若n=1,则直接返回值
{
free(cur);
pre[1] = '\0';
return pre;
}
//若不为1,开始一项一项构造
int m = 2;//从第m项开始构造
strlen = 1;//m-1的长度
while(m<=n)
{
int icould = 1;//记录相同元素个数
int end = 0;//增加元素的数组下标
for(int i =0;i<strlen;++i)
{
if(pur[i] == pur[i+1])
{
icould++;
}
else
{
cur[end++] = icould + '0';// int的icould要转换成char
cur[end++] = pre[i];
icould = 1;
}
}
cur[end] = '\0';
strlen = icould;
memcpy(cur,pur,maxsize*sizeof(char));
m++;
}
free(pur);
return cur;
**补充:
1.memcpy:函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中。
2.函数原型:void *memcpy(void destin, void source, unsigned n);
destin是存储数据内容的,source是用来被复制的,n为字节数
3.与strcpy不同:
A.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
B、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
C、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy