【发布时间】:2020-11-07 07:15:27
【问题描述】:
我有一个测试问题和解决方案。
问题是:编写一个函数,如果我们可以将一个数组分成两个不同的组,它们的总和相等,则返回 1,否则返回 0。 例如:数组:[1,4,0,3] 可以分为两组,它们的和相等,因此:1+3=0+4
建议的解决方案如下:
#include<stdio.h>
int can_split(int arr[], int n, int sum1, int sum2); // Function Signature
int can_split(int arr[], int n, int sum1, int sum2)
{
if (n == 0)
return sum1 == sum2;
return can_split(arr + 1, n - 1, sum1 + arr[0], sum2) || can_split(arr + 1, n - 1, sum1, sum2 + arr[0]);
}
int main()
{
int sum1_main = 0, sum2_main = 0;
int arr_main[] = { 1,2,4 };
printf("Function returned: %d", can_split(arr_main, 4, sum1_main, sum2_main));
return 0;
}
我不明白的是这条线的想法:
return can_split(arr + 1, n - 1, sum1 + arr[0], sum2) || can_split(arr + 1, n - 1, sum1, sum2 + arr[0]);
当涉及到复杂的问题时,递归对我来说是一个非常困难的话题。
如果有人能解释这行是如何工作的以及老师为什么要写 || 将非常感激? 我知道它的意思是“或”,但它到底是做什么的呢?
【问题讨论】:
-
当第一部分为真时,返回真,第二部分不执行。否则返回第二部分的返回值。
-
在递归的第一级,该算法将数组的第一个元素分派到第一个或第二个子集,分别为 sum1 和 sum2:|| 的左侧和右侧。在递归的第二级,它对数组的第二个元素执行相同的操作,依此类推。它最终遍历一个二叉树,在子集 1 或子集 2 中分派元素,当它找到 sum1 = sum2 的叶子时结束搜索
-
main中的can_split(arr_main, 4, sum1_main, sum2_main))不应该是can_split(arr_main, 3, sum1_main, sum2_main)),以int arr_main[] = { 1,2,4 };的数组为参数n是元素的数量吗? --- 最好使用can_split(arr_main, sizeof(arr_main) / sizeof(*arr_main), sum1_main, sum2_main))。
标签: arrays c xcode recursion numbers