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