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