如何使递归C程序更高效?

如何使递归C程序更高效?,c,arrays,optimization,recursion,malloc,C,Arrays,Optimization,Recursion,Malloc,我必须用c编写一个程序,找到验证此条件的对数: i<j && a[i]>a[j] ia[j] []是包含N个元素的数组 示例:给定N=4和a={1,7,2,0}对数为4:(1,0)、(7,2)、(7,0)、(2,0) 我写了这段代码,但效率很低: #include <stdio.h> #include <stdlib.h> #define N 4 int count(int a[],int i, int j); int main(){

我必须用c编写一个程序,找到验证此条件的对数:

i<j && a[i]>a[j]
ia[j]
[]是包含N个元素的数组

示例:给定N=4a={1,7,2,0}对数为4(1,0)、(7,2)、(7,0)、(2,0)

我写了这段代码,但效率很低:

#include <stdio.h>
#include <stdlib.h>
#define N 4

int count(int a[],int i, int j);

int main(){

   int i,c=0;

   int a[]={1,7,2,0};

   for(i=0; i<N-1;i++)
      c+=count(a,i,N-1);

   printf("%d",c);

   return 0;
}

int count(int a[N], int i, int j){
    if(j<0)
       return 0;

     if(i<j && a[i]>a[j])
        return 1+count(a,i,j-1);

     return 0+count(a,i,j-1);
}
#包括
#包括
#定义n4
整数计数(整数a[],整数i,整数j);
int main(){
int i,c=0;
int a[]={1,7,2,0};

对于(i=0;i基本上,您需要计算数组中的反转数。这可以通过使用类似于合并排序算法的技术来实现。我建议您查看以下文章:

说到动态数组生成,您可能想知道,自C99以来,有(它们的大小不再需要是常量)


若你们真的想要或者需要使用malloc,你们应该先看看指针。在你们知道如何处理指针之后,一切都会变得清晰,因为malloc只是为你们设置了一个可以玩指针的游乐场。

基本上,你们需要在数组中计算反转。这可以通过使用和我类似的技术来实现rge排序算法。我建议您看看下面的文章:

说到动态数组生成,您可能想知道,自C99以来,有(它们的大小不再需要是常量)


如果你真的想或需要使用malloc,你应该先看看指针。在你知道如何处理指针之后,一切都会变得清晰,因为malloc只是为你设置了一个可以使用指针的平台。

我不确定你为什么要使用递归,或者它如何能让它更快。我建议用双精度的oop,因为它更容易阅读:

for(i = 0 ; i < N-1 ; i++)
    for(j = i+1 ; j < N ; j++)
        c += (a[i]>a[j]) ? 1 : 0;
(i=0;i 对于(j=i+1;ja[j])?1:0;
我不确定您为什么要使用递归,或者如何使其更快。我建议使用双for循环,因为它更易于阅读:

for(i = 0 ; i < N-1 ; i++)
    for(j = i+1 ; j < N ; j++)
        c += (a[i]>a[j]) ? 1 : 0;
(i=0;i 对于(j=i+1;ja[j])?1:0;
一般来说,递归解决方案中的递归(加法)后会有连续性。您可以使用累加器作为一个参数来创建返回值,这样做会更好。对于某些编译器,递归将优化为循环:

int count(int a[N], int i, int j)
{
    return count_aux(a, i, j, 0);
}

int count_aux(int a[N], int i, int j, int acc)
{
    if ( j<0 )
       return acc;
    else
       return count_aux(a,i,j-1, ( i<j && a[i] > a[j] ? acc+1 : acc ));
}
int计数(int a[N],int i,int j)
{
返回计数_aux(a,i,j,0);
}
整数计数辅助(整数a[N],整数i,整数j,整数acc)
{

如果(j通常,您的递归解决方案在递归之后具有连续性(加法)。您可以使用累加器作为一个参数来创建返回值,从而使其更好,对于某些编译器,递归将优化为循环:

int count(int a[N], int i, int j)
{
    return count_aux(a, i, j, 0);
}

int count_aux(int a[N], int i, int j, int acc)
{
    if ( j<0 )
       return acc;
    else
       return count_aux(a,i,j-1, ( i<j && a[i] > a[j] ? acc+1 : acc ));
}
int计数(int a[N],int i,int j)
{
返回计数_aux(a,i,j,0);
}
整数计数辅助(整数a[N],整数i,整数j,整数acc)
{

如果(首先,我看不出你在哪里打印出任何对。我遗漏了什么?你为什么认为这不高效?在堆栈上分配内存是非常高效的-只是减少堆栈指针。是否存在必须使用函数的约束?递归函数?最直接的方法是在正在检查的条件(可以在
main()
或简单的非递归函数中内联编写)。在
main()
中分配数组-不在
count()
int*b=malloc(200*sizeof(*b));如果(b!=0){for(int j=0;j<200;j++)b[j]=rand();…现在检查减少的对数…}
。是的,我必须使用递归函数;而且我只需要打印出对的数量,而不是对。首先,我看不出您在哪里打印出任何对。我遗漏了一些东西?为什么您认为这不高效?在堆栈上分配内存非常高效-只是减少堆栈指针。是否存在这样的约束必须使用函数?递归函数?最直接的方法是围绕正在检查的条件使用两个循环(可以在
main()
或简单的非递归函数中内联编写)。在
main()
-而不是
count()
中分配数组;如果(b!=0){对于(intj=0;j<200;j++)b[j]=rand();…现在检查递减对…}
。是的,我必须使用递归函数;而且我只需要打印出对的数量,而不是对的数量。我知道双循环更容易……老师给了我们这个练习,并告诉我们使用递归函数来解决它,他还提到了一些关于mergesort的内容,但我不知道如何在这里应用它。OKé,然后忽略我的答案:).已经有一段时间没有使用递归或mergesort了,所以在没有先测试的情况下不要尝试回答它。我知道双循环更容易…老师给了我们这个练习,并告诉我们使用递归函数来解决它,他还提到了一些关于mergesort的内容,但我不知道如何在这里应用它好吧,然后忽略我的答案:).已经有一段时间没有使用递归或合并排序了,所以在没有先测试的情况下,我不会尝试回答它。谢谢!你是对的,我需要用另一种方式来看待这个问题;计算数组中反转数的程序的复杂度为O(n*logn)这相当于mergesort复杂度现在我只需要找到一种方法来创建数组DynamicAllyInterest。Geeksforgeks.org上的代码像筛子一样泄漏,但这很容易修复。我测量并计时了代码的两个变体,对于大约150个数组,简单的二次代码优于更复杂的合并排序代码。H不过,O(N*N)行为很快就会比合并排序代码的O(N logn)行为花费更多。谢谢!你说得对,我需要看看这个问题