计蒜客“伯爵说”问题(Count-And-Say)——C语言

计蒜客“伯爵说”问题(Count-And-Say)

“伯爵说”序列如下:1,11,21,1211,111221,…。其1读作one 1或者1111读作two 1s或者2121读作one 2,one 1或者1211

输入格式

多组输入,读到文件结束。每组输入给定一个整数 n(1≤n≤30)。

输出格式

输出第 n 个序列。注意,整数序列以字符串的形式表示。

样例输入

6

样例输出

312211

提示:

类似于求“斐波那契”数列的第 n 项哦~


这道题目其实不难解,后一项的值来自于前一项,有点类似于斐波那契数列,但是又不像。
关于此题的思路,就是用while从字符串的开头(i=0)开始,逐一向下判断,一直到i+1项为’\0’为止,如果i+1项的值等于第i项的值的话,那么i++,然后继续向下判断,直到第i项的值不再等于i++。然后就把这个数字重复的次数和数字再另一个字符串内保存起来,再把计数的变量初始化,i++,然后继续判断。
考虑到最后的数字可能没法保存,因此在while的外部再单独保存一遍。
以下就是我自己写的代码,已经添加了超级多的注释。

#include
#include
#include

char *CountAndSay(int n);//执行Count And Say 
void CountSay(char *str1,char *str2);//得到每次CountSay后的结果 
void Solve();

int main()
{
	Solve();
	return 0;
}

void Solve()
{
	int n;//存储CountSay的次数 
	while(scanf("%d",&n)!=EOF)//一直输入到文件尾 
	{
		printf("%s\n",CountAndSay(n));//将最后的结果打印出来 
	}
}

char *CountAndSay(int n)
{
	char *str1,*str2;
	str1=(char*)malloc(sizeof(char)*99999);//给str1一个较大的内存 
	str2=(char*)malloc(sizeof(char)*99999);//给str2一个较大的内存 
	memset(str1,0,99999);//给str1初始化
	memset(str2,0,99999);//给str2初始化
	strcpy(str1,"1");//给str1初始化为'1'的开始
	for(int i=1;i<n;i++)//由于'1'是第一次Say的内容,因此循环n-1次
	{
		CountSay(str1,str2);//进行一次CountSay,并把结果存储到str2内 
		strcpy(str1,str2);//使str1的内容等于str2的内容,完成一次CountSay 
	}
	free(str2);//释放掉无用的str2的内存 
	return str1;//返回最后一次CountSay的结果 
}

void CountSay(char *str1,char *str2)
{
	int count=1,i=0,j=0;//count用于存储相同数字出现的次数,最少1次。i是校验到的str1的位置,j是在str2添加的位置 
	while(str1[i+1]!='\0')//如果str1[i+1]的内容为'\0'就跳出循环 
	{
		if(str1[i]==str1[i+1])//判断str1在i处的字符是否和i+1处的相等,相等count+1 
		{
			i++;//向后移一位 
			count++;//重复数字的个数+1 
		}
		else
		{
			str2[j++]=count+'0';//第一位是相同数字出现的次数,先赋值然后j++; 
			str2[j++]=str1[i];//第二位是重复的数字,先赋值然后j++; 
			i++;//向后移一位
			count=1;//count初始化 
		}
	}
	//以下两行代码用于添加最后的一个重复数字,如1121,添加的是最后一个1的出现次数和数字。 
	str2[j++]=count+'0';//第一位是相同数字出现的次数,先赋值然后j++; 
	str2[j++]=str1[i];//第二位是重复的数字,先赋值然后j++; 
}

谢谢观看

你可能感兴趣的:(计蒜客“伯爵说”问题(Count-And-Say)——C语言)