当前位置: 首页 > 知识库问答 >
问题:

指针和递归有问题

后易安
2023-03-14

我现在正在做一个关于Collatz序列的问题。我必须找到最长的Collatz序列,如果我们从范围1开始,。。。,数字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,…,之间每个数字n的Collatz序列,。。。,1000000并检查哪个序列最长。但这并不高效。

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

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

共有3个答案

凌啸
2023-03-14

>

  • 使用*(数组n)数组[n]而不是(*数组)[n]访问nth变量。

    由于长度是一个数组,因此仅使用名称调用函数将传递其地址。

    for循环中的小错误。for(int n=1; 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-03-14
    匿名用户

    我想你必须这样调用函数

    recursion(n,length);
    

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

    您也在指向int的指针中接收它。因此,您可以在函数中正常使用数组[]。像数组

    卢翔宇
    2023-03-14

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

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

    此外,在您的main函数中,使用递归(n,长度)调用递归,而不是递归(n,

     类似资料:
    • 我必须编写一个递归函数来检查两个相同大小的给定数组是否具有相同的元素,但它们可能顺序不同。 我认为最优雅的解决方案是对两个数组进行排序,然后比较每个元素,但我不知道如何在一个递归函数中对两个阵列进行排序。 所以我有另一个想法,使用线性搜索,获取数组1的最后一个元素并在数组2中搜索它,如果它在那里,使用移位函数,移动该元素前面的所有元素(在数组2中)并返回true,如果没有找到它,则返回false。

    • 我现在正在实现模拟N体问题的Barnes-Hut算法。我只想问关于建筑树的部分。 我做了两个函数来为它构建树。 我递归地构建树,并在构建时打印每个节点的数据,一切看起来都是正确的,但当程序返回到主函数时,只有树的根和根的子节点存储值。其他节点的值没有被存储,这很奇怪,因为我在递归过程中打印了它们,它们应该被存储。 这是经过修改的代码的一部分,我认为问题可能在哪里: 下面是函数set_root_an

    • 指针变量也是变量,是变量就可以任意赋值,不要越界即可(32位编译器指针大小为4字节,64位编译器指针大小为8字节),但是,任意数值赋值给指针变量没有意义,因为这样的指针就成了野指针,此指针指向的区域是未知(操作系统不允许操作此指针指向的内存区域)。所以,野指针不会直接引发错误,操作野指针指向的内存区域才会出问题。 int a = 100; int *p; p = a; //把a的值赋值给指针变量p

    • 我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为new

    • 001.Two Sum[E] 1.题目 Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution. Example: G

    • 指针不是存放首地址吗,怎么不一样呢