【问题标题】:Having problems with pointers and recursions指针和递归有问题
【发布时间】:2015-07-30 16:35:03
【问题描述】:

我现在正在处理有关 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。

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

更聪明的算法是利用这样一个事实,即给定一个 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){

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

【问题讨论】:

  • 从(哎呀)626331开始?

标签: c algorithm pointers recursion


【解决方案1】:

array 是一个int**array 因此是int。你不能说int i; i[0],那你为什么可以说(*array)[0]

只需说array[n]而不是(*array)[n]即可正常访问它。

另外,在您的 main 函数中,使用 recursion(n, length); 而不是 recursion(n, &amp;length); 调用 recursion。您传递的是数组,而不是数组的 指针

【讨论】:

    【解决方案2】:

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

    recursion(n,length);
    

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

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

    【讨论】:

      【解决方案3】:
      1. 使用*(array + n)array[n] 而不是(*array)[n] 来访问nth 变量。

      2. 由于length 是一个数组,因此仅使用名称调用函数会传递它的地址。

      3. for 循环中的小错误。 for(int n=1; n&lt;=10;i++){for(int n=1; n&lt;=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;
      }
      

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-25
        • 1970-01-01
        相关资源
        最近更新 更多