指针和递归有问题

时间:2015-07-30 16:35:04

标签: c algorithm pointers recursion

我现在正在解决Collat​​z序列问题。如果我们从1,...,1000000范围内的数字开始,我必须找到最长的Collat​​z序列。数字n的Collat​​z序列定义为: 如果n mod 2 == 0则下一个数字是n / 2。如果n mod 2!= 0,那么下一个数字是3 * n + 1。 n = 10的顺序是10,5,16,8,4,2,1。

当然,如果我们以天真的方式解决这个问题,我们会计算每个数字n的Collat​​z序列在1,...,1000000之间,并检查哪个序列最长。但这并不高效。

更聪明的算法是使用给定Collat​​z序列的事实,通过不查看前几个元素获得的序列也是Collat​​z序列。因此,如果我们计算n = 10的序列,即10,5,16,8,4,2,1那么序列5,16,8,4,2,1也是一个Collat​​z序列,我们立即找到了长度通过计算n = 10的序列,得到n = 5,n = 16,n = 8,n = 4,n = 2和n = 1的Collat​​z序列。

考虑到这个想法,我使用指针和递归在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){

我不知道为什么会收到这些警告和错误。

3 个答案:

答案 0 :(得分:3)

arrayint*。因此,*arrayint。你不能说int i; i[0],那你为什么能说(*array)[0]

只需通过array[n]代替(*array)[n],即可正常访问。

另外,在main功能中,使用recursion拨打recursion(n, length);,而不是recursion(n, &length);。您将数组传递给数组,而不是指针

答案 1 :(得分:2)

我认为你必须像这样调用这个函数

recursion(n,length);

因为,数组名称包含数组的第一个元素的地址。

你也在pointer to int收到它。因此,您可以在函数中正常使用array[]。与array[n]

一样

答案 2 :(得分:1)

  1. 使用array[n](*array)[n]代替n来访问length变量。

  2. 由于for(int n=1; n<=10;i++){是一个数组,因此仅使用名称调用该函数会将其传递给地址。

  3. for循环中的小错误。 for(int n=1; n<=10;n++){#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;n++){ recursion(n,length);//use the function for each n } for(int i=0;i<10;i++){ printf("%d\n",length[i]); } return 0; }

  4. 这些更改修复了编译错误。

    db.UserStatistics