我们的教授给了我们以下的任务:
“正确”系列是指其成员总和等于其第一个成员的索引的系列。
程序应该在一系列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);
}
我在这里做错了什么?
我们不应该在这个任务中使用循环。
答案 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)
首先,编写一个函数,测试一系列给定的起始索引和给定长度的“其成员总和”条件。然后,编写第二个函数,查找数组中最长的序列,其中只给出起始索引(以递减顺序循环子序列长度应该这样做);这个功能可以调用第一个。最后,编写第三个循环遍历所有起始索引的函数,调用函数二。
哦等等,不再需要递归了,所以很多大脑扭曲都消失了......: - )