【发布时间】:2015-07-30 16:35:03
【问题描述】:
我现在正在处理有关 Collatz 序列的问题。如果我们从 1,...,1000000 范围内的数字开始,我必须找到最长的 Collatz 序列。数 n 的 Collatz 序列定义为: 如果 n mod 2 == 0 那么下一个数字是 n/2。如果 n mod 2 != 0 那么下一个数字是 3*n+1。 n=10 的序列是 10,5,16,8,4,2,1。
当然,如果我们以天真的方式解决这个问题,我们将计算 1,...,1000000 之间每个数字 n 的 Collatz 序列,并检查哪个序列最长。不过这样效率不高。
更聪明的算法是利用这样一个事实,即给定一个 Collatz 序列,通过不查看前几个元素获得的序列也是一个 Collatz 序列。因此,如果我们计算 n=10 的序列,即 10,5,16,8,4,2,1 那么序列 5,16,8,4,2,1 也是一个 Collatz 序列,我们立即找到了长度只需计算 n=10 的序列即可得到 n=5,n=16,n=8,n=4,n=2 和 n=1 的 Collatz 序列。
考虑到这个想法,我使用指针和递归在 C 中编写了以下代码。
#include <stdio.h>
#include <stdlib.h>
int recursion(int n, int *array){
if((*array)[n]==0){//check if I already have the length of the sequence for this n
if(n/2==(double)n/(double)2){//check if n mod 2 == 0
(*array)[n]=recursion(n/2,array)+1;
}
else{
(*array)[n]=recursion(3*n+1,array)+1;
}
}
else{
return 0;
}
}
int main(int argc, char **argv){
int length[100];//this array will contain the lengths of sequences,
//I will only do it for n=1 up to n=10, but I have to have a bigger
//array since the Collatz sequence elements can be higher than 10
for (int i=0;i<100;i++){
length[i]=0;
}
length[0]=1;//the Collatz sequence for n=1 has length 1
for(int n=1; n<=10;i++){
recursion(n,&length);//use the function for each n
}
for(int i=0;i<10;i++){
printf("%d\n",length[i]);
}
return 0;
}
如果我编译这段代码,我会得到几个错误:
main.c:5:13: error: subscripted value is not an array, pointer, or vector
if((*array)[n]==0){
~~~~~~~~^~
main.c:7:12: error: subscripted value is not an array, pointer, or vector
(*array)[n]=recursion(n/2,array)+1;
~~~~~~~~^~
main.c:10:12: error: subscripted value is not an array, pointer, or vector
(*array)[n]=recursion(3*n+1,array)+1;
~~~~~~~~^~
main.c:25:15: warning: incompatible pointer types passing 'int (*)[100]' to
parameter of type 'int *' [-Wincompatible-pointer-types]
recursion(i,&length);
^~~~~~~
main.c:4:27: note: passing argument to parameter 'array' here
int recursion(int n, int *array){
我不知道为什么会收到这些警告和错误。
【问题讨论】:
-
从(哎呀)626331开始?
标签: c algorithm pointers recursion