在C中递归地解决问题

时间:2010-05-14 13:00:00

标签: c recursion

我们的教授给了我们以下的任务:

  

“正确”系列是指其成员总和等于其第一个成员的索引的系列。

程序应该在一系列n个数字中找到最长“正确”系列的长度。

例如:如果输入系列为arr[4]={1, 1, 0, 0} 输出(最长的“正确”系列)将为3 arr[0]=1. 0!=1因此,此处最长的系列是0 arr[1]=1,and 1=1.但以下成员也总计为1,如下所示:
1=arr[1]+arr[2]+arr[3] = 1+ 0 + 0,因此这里最长的系列是3

此示例中的输出为3

这是我到目前为止所做的:

int solve(int arr[], int index, int length,int sum_so_far)
{
     int maxwith,maxwithout;

     if(index==length)
         return 0;

     maxwith = 1+ solve(arr,index+1,length,sum_so_far+arr[index]);
     maxwithout = solve(arr,index+1,length,arr[index+1]);

     if(sum_so_far+arr[index]==index)
         if(maxwith>maxwithout) 
            return maxwith;

     return maxwithout;

     return 0;
}



int longestIndex(int arr[], int index,int length)
{
     return solve(arr,0,length,0);
}

我在这里做错了什么?

我们不应该在这个任务中使用循环。

3 个答案:

答案 0 :(得分:3)

嗯,这个程序有几个问题。

最明显的是,“返回maxwithout;返回0;”应该给出一个编译错误:没有办法到达最后一个return语句。

其次,您正在递归以解决“maxwith”路径,直到到达数组的末尾。然后你将进入maxwithout,第一次用index = 4击中它。我不认为这会起作用。

坦率地说,我不认为这个问题确实需要递归。最自然的解决方案是嵌套循环:

for (int start=0;start<length;++start)
{
  for (int end=start;end<length;++end)
  {
    // calculate the sum of arr[start]->arr[end] and compare to start
  }
}

或者那种效果。

问题是否需要通过递归来解决问题,或者这只是您在良好解决方案中的第一个想法?

修改

好的,所以你必须使用递归。我想这一课的目的是学习使用递归,而不是以最自然或最有效的方式解决问题。 (就个人而言,我认为老师应该提出一个问题,递归是一个自然的解决方案,但我想我们今天不会在这里批评老师。)

我不想为你做功课,但我会给你一个提示。您可以使用递归来模拟循环,方法是将break条件放在函数的开头,并使用+1参数将递归调用放在函数的末尾。也就是说,而不是写

for (int x=0;x<10;++x) { ... whatever ...}

你可以写

void forx(int x)
{
  if (x>=10)
    return;
  ... whatever ...
  forx(x+1);
}

所以在这种情况下,我会做类似的事情:

void endloop(int start, int end)
{
  if (end>=arrayLength)
    return;
  ... work on running total ...
  endloop(start, end+1);
}

void startloop(int start)
{
  if (start>=arrayLength)
    return;
  endloop(start, start);
}
int main()
{
  ... setup ...
  startloop(0);
  ... output ...
}

参数列表不一定完整。正如我所说,我不想为你做功课,只是给你一个开始的提示。

答案 1 :(得分:1)

在我看来,问题出在这里:

if(sum_so_far+arr[index]==index)

您将目前的总和与当前索引进行比较,但您应该将其与系列中的第一个索引进行比较。在我看来,如果你开始使用arr的最后一个元素朝向第一个元素,而不是按照自然顺序开始,那会更好。这样你开始对元素求和,直到总和等于当前索引。

答案 2 :(得分:1)

首先,编写一个函数,测试一系列给定的起始索引和给定长度的“其成员总和”条件。然后,编写第二个函数,查找数组中最长的序列,其中只给出起始索引(以递减顺序循环子序列长度应该这样做);这个功能可以调用第一个。最后,编写第三个循环遍历所有起始索引的函数,调用函数二。

哦等等,不再需要递归了,所以很多大脑扭曲都消失了......: - )