请找到这段代码中的漏洞,检查给定数组中是否存在总和为0的子数组(我没有得到所需的输出)。我是编程新手,所以欢迎任何提示,建议。我真的很想改进。另外,如果我可以使用其他逻辑,请在评论中告诉我。
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a,const void* b);
void FindO(int * A, int n);
int main()
{
int i,n;
int A[] = {-7,-4,-3,1,2,3,10};
n = sizeof(A)/sizeof(A[0]);
qsort(A,n, sizeof(int), compare);
printf("The sorted array is: ");
for (i = 0;i < n; i++)
{
printf("%d ", A[i]);
}
FindO(A, n);
return 0;
}
int compare(const void* a,const void* b)
{
int l = *(int *)a;
int r = *(int *)b;
return (l-r);
}
void FindO(int * A, int n)
{
int mid = n/2;
int i, j = mid;
int sum = A[mid];
printf("\n%d ", sum);
while(i >= 0 && j <n)
{
if(sum ==0)
{printf("\nFound it!");
return;}
else if(sum > 0)
{
i--;
sum = sum + A[i];
}
else
{
j++;
sum = sum + A[j];
}
}
if(sum !=0)
{printf("\nNot found Buddy!");
}
}
答案 0 :(得分:1)
你没有说你的问题是什么。
但首先,您不会初始化i
,这很可能会在您使用它时导致分段错误:
while(i >= 0 && j <n)
或随后对其的引用。
您可以使用,
逗号分隔变量,但初始化:
int i, j = mid;
仅影响j
而非i
。
答案 1 :(得分:1)
我不知道你的算法如何获得数组的所有子数组,所以我编写了自己的解决方案。
这个用递归计算数组中子数组的所有元素,并检查总和是否等于零:
void FindO_in(const int *A, size_t n, int sum, size_t numslen)
{
assert(A != NULL);
assert(n >= 0);
assert(numslen >= 0);
if (n == 0) {
if (numslen == 0) {
// no numbers summed, ignored
return;
}
if (sum != 0) return;
if (sum == 0) {
printf("Zero pal!");
} else {
printf("Not zero buddy!");
}
printf("\n");
return;
}
--n;
// next without incrementing sum
FindO_in(&A[1], n, sum, numslen);
// protec against overflow
assert(!(A[0] > 0 ? (sum > INT_MAX - A[0]) : (sum < INT_MIN - A[0])));
// next with incremented sum
sum += A[0];
++numslen;
FindO_in(&A[1], n, sum, numslen);
}
void FindO(const int *A, size_t n)
{
FindO_in(A, n, 0, 0);
}
以下是更通用的解决方案。首先,我使用递归生成数组的所有子数据。然后对于每个子数组,我调用一个回调函数,该函数检查该子数组的元素总和是否等于零。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#define try(expr) ((expr) ? (void)0 : (assert(expr), (void)fprintf(stderr, "Expression `%s` failed\n", #expr), abort()))
static void check0(const int *arr, size_t n)
{
int sum = 0;
for(size_t i = 0; i < n; ++i) {
try(!(arr[0] > 0 ? (sum > INT_MAX - arr[0]) : (sum < INT_MIN - arr[0])));
sum += arr[i];
}
if (sum != 0) return;
printf("The sum of numbers {");
for(size_t i = 0; i < n; ++i) {
printf(" %d", arr[i]);
}
printf("} is equal %d. ", sum);
if (sum == 0) {
printf("Zero pal!");
} else {
printf("Not zero buddy!");
}
printf("\n");
}
static void gensubarrays_in(const int *arr, size_t n, int *subarr, size_t subarrlen, void (*callback)(const int*, size_t))
{
assert(arr != NULL);
assert(n >= 0);
assert(subarr != NULL);
if (n == 0) {
// empty subarray - ignore
if (subarrlen == 0) return;
callback(subarr, subarrlen);
return;
}
--n;
gensubarrays_in(&arr[1], n, subarr, subarrlen, callback);
subarr[subarrlen++] = arr[0];
gensubarrays_in(&arr[1], n, subarr, subarrlen, callback);
}
static void gensubarrays(const int *arr, size_t n, void (*callback)(const int*, size_t))
{
// just a temp variable, to know, which numbers are summed
int *subarr = calloc(sizeof(int), n);
try(subarr != NULL);
gensubarrays_in(arr, n, subarr, 0, callback);
free(subarr);
}
int main()
{
int A[] = {-7,-4,-3,1,2,3,10};
const size_t n = sizeof(A)/sizeof(A[0]);
printf("The array is: ");
for (size_t i = 0; i < n; i++) {
printf("%d ", A[i]);
}
printf("\n");
gensubarrays(A, n, check0);
return 0;
}
:)