天天看点

C语言Hailstone Sequence雹石序列相关练习

C语言Hailstone Sequence雹石序列相关练习

希尔斯顿序列似乎总是返回到1。如果前一个数字是奇数,则下一个数字变为前一个数字的一半,如果奇数,那么下一个变成3 * n + 1。 例如,当我们从数字开始6,我们得到序列:6,3,10,5,16,8,4,2,1有九个数字,当我们从11开始,序列更长,包含15个数字:11,34,17,52,26,13,40,20,10,5,16,8,4,2,1。

练习编写一个程序:

•显示哪个初始数字(小于50000)创建最长的冰雹序列。

•显示出现最大数字(小于50000)的初始数字顺序。

初级答案:

#include <stdio.h>
#include <stdlib.h>

#define N 50000//定义范围小于50000
int hailstone(int i)//函数为了计算雹石序列并返回长度值
{
	int length=1;

	while(i!=1)//得到雹石序列
	{
		length++;
		if (i%2==0)
		{
			i=i/2;
		}
		else
		{
			i=3*i+1;
		}
	
	}
	return length;
}

int hailstonemax(int i)//函数计算雹石序列并返回长度值
{
	int max=1;
	while(i!=1)//得到雹石序列

	{
		if (i%2==0)
		{
			i=i/2;
		}
		else
		{
			i=3*i+1;
		}
		if(i>max)
		{
			max=i;
		}
	
	}
	return max;
}

int main( )
{
    int j,n,num,jnum,nummax=1,max=0,jmax;
	for(j=1;j<N;j++)
	{
	
	
		n=hailstone(j);
		if(max<n)//比较不同序列的长度
		{
			max=n;//最长的雹石序列
			jmax=j;//最长雹石序列所对应的初始数字
		}
		
		
		num=hailstonemax(j);
		if(nummax<num)
		{
			nummax=num;//雹石序列中的最大数字
			jnum=j;//雹石序列中最大数字所对应的初始数字
		}

	}
	
	 printf("最长的雹石序列的长度是 %d 初始数字是%d.\n", max, jmax);
	 printf("最大的雹石序列是%d 对应的初始数字是 %d.\n", nummax, jnum);
	
	return 0;
}

           

改进版:

#include<stdio.h>

define MAX 50000

int nexthail(int n);//得到雹石数列的下一个数字
void lensq(int s,int *c,int *m);
           
int main(void)
{
   int l,ml=0;
   int s;
   for(s=1;s<MAX;s++)
   {
    l=lenseq(s,&l,&m);
	ifmx(l,&ml,"长度",s);
	ifmx(m,&ms,"最大值",s);
   }
    return 0;
}

void ifmx(int l,int *ml,char *str, int s)//利用指针使得一个函数中可以同时返回几个不同的值,避免相似代码的重复使用
{
	if(l>*ml){
		*ml=l;
		printf(初始值为%5d, %s=%4d\n",s,str,*ml);
void lenseq(int s,int *c,int *m)//初始数字应该大于一,如果等于1时则不再执行nexthail()
{
	*c=0;
	*m=0;
    while (s>1){
		s=nexthail(s);
		if(s>*m){
			*m=s;
			
		*c=*c+1;
	}
	return c;
}

int nexthail(int n)
{
	if(n%2==0){
		return n/2;
	}
	return 3*n+1;
}
	
	
           

改进版2:

#include<stdio.h>

define MAX 50000

typeof unsigned long hailnum;

hailnum nexthail(int n);
void lenseq(int s,int *c,int *m);
void ifmx(int l,int *ml,char *str, int s);

int main(void)
{
   int l,ml=0;
   int s;
   for(s=1;s<MAX;s++)
   {
    l=lenseq(s,&l,&m);
	ifmx(l,&ml,"长度",s);
	ifmx(m,&ms,"最大值",s);
   }
    return 0;
}

void ifmx(int l,int *ml,char *str, int s)
{
	if(l>*ml){
		*ml=l;
		printf(初始值为%5d, %s=%4d\n",s,str,*ml);
void lenseq(int s,int *c,int *m)
{
	*c=0;
	*m=0;
    while (s>1){
		s=nexthail(s);
		if(s>*m){
			*m=s;
			
		*c=*c+1;
	}
	return c;
}

int nexthail(int n)
{
	if(n%2==0){
		return n/2;
	}
	return 3*n+1;
}
	
           

本人新手小白,如果有什么还可以改进的地方,请大神多多指教。

更多关于雹石数列的其他编程语言的示例可参考:

https://rosettacode.org/wiki/Hailstone_sequence

继续阅读